Използване на инструкции за обработка за задаване на променлива в XSLT

Използвам asciidoc с бекенда на docbook и се опитвам да предам URL като променлива от asciidoc до docbook, където променливата може да има различни стойности в целия документ. Например, искам потребителите ми да могат да правят нещо като:

# url="http://foo/

== some text

Some para....

# url="http://bar/

== some text

Some para....

Идеята ми беше да използвам блокове за преминаване, за да добавя инструкции за обработка, които могат да бъдат взети в docbook, напр.

pass::[<?my_url http://foo ?>]
== some title

some para...

Това, което не мога да разбера как да направя, е да напиша XSLT, който изразява следното: "намерете предишната инструкция за обработка, наречена my_url, и използвайте нейното съдържание, за да зададете стойността на променлива"

Следвайки указанията, дадени в http://www.sagehill.net/docbookxsl/ProcessingInstructions.html Опитах да използвам dbhtml PI, напр.:

<?dbhtml my_url="http://foo.com" ?>

и в моя XSL:

  <xsl:template match="ulink[@role='edit_me']">
    <xsl:variable name="my_url">  
      <xsl:call-template name="dbhtml-attribute">  
        <xsl:with-param name="pis"  
             select="ancestor-or-self::entry/processing-instruction('dbhtml')"/>  
        <xsl:with-param name="attribute" select="'my_url'"/>  
      </xsl:call-template>
    </xsl:variable>

    GOT: <xsl:value-of select="$my_url" />
  </xsl:template>

Но напълно не мога да извлека стойността, която преследвам. Помощта е оценена с благодарност.

Добавен примерен XML

Например вземете този примерен XML документ:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">

<book lang="en">
<bookinfo>
    <title>Title one</title>
</bookinfo>

<?my_url http://foo.com ?>

<preface>
    <title><ulink role="edit_me" url="test.asciidoc">Edit me</ulink></title>
</preface>

<?my_url http://bar.com ?>

<chapter id="_title_two">
    <title>Title two<ulink role="edit_me" url="test.asciidoc">Edit me</ulink></title>
    <simpara>Some text</simpara>
</chapter>

<chapter id="_title_three">
    <title>Title three<ulink role="edit_me" url="test.asciidoc">Edit me</ulink></title>
    <simpara>More text</simpara>
</chapter>

</book>

Искам да изобразя всяка от edit_me връзките, като използвам URL адреса, посочен в предходната my_url инструкция за обработка. Така че първата връзка ще използва foo.com, докато следващите две ще използват bar.com.


person DrTech    schedule 11.04.2015    source източник
comment
dbhtl-атрибут изглежда като печатна грешка. Има шаблон, наречен dbhtml-attribute в pi.xsl в DocBook-XSL. Имахте предвид да извикате този шаблон?   -  person mzjn    schedule 11.04.2015
comment
да, това беше правописна грешка във въпроса, но беше правилно в моя (неуспешен) код. коригирах го, благодаря   -  person DrTech    schedule 11.04.2015
comment
Примерен docbook XML, който да съответства на вашия пример, би бил полезен. Трудно е да се определи от вашия псевдокод, описващ XML структурата, защо вашият шаблон не произвежда правилния изход.   -  person Mads Hansen    schedule 11.04.2015
comment
@MadsHansen Добавих конкретен пример, благодаря   -  person DrTech    schedule 11.04.2015


Отговори (2)


Вие използвате:

select="ancestor-or-self::entry/processing-instruction('dbhtml')"

но във вашия пример няма entry и всички инструкции за обработка са деца на коренния елемент book.

Звучи сякаш наистина искате да вземете стойността на най-близката предходна инструкция за обработка. Например прилагане на:

<xsl:template match="ulink[@role='edit_me']">
    <xsl:copy>
    <xsl:attribute name="url">
        <xsl:value-of select="preceding::processing-instruction('my_url')[1]"/>
    </xsl:attribute>
    </xsl:copy>
</xsl:template> 

(заедно с шаблона за трансформиране на самоличността и шаблона за потискане на инструкциите за обработка) ще доведе до:

<?xml version="1.0" encoding="utf-8"?>
<book lang="en">
   <bookinfo>
      <title>Title one</title>
   </bookinfo>
   <preface>
      <title>
         <ulink url="http://foo.com "/>
      </title>
   </preface>
   <chapter id="_title_two">
      <title>Title two<ulink url="http://bar.com "/>
      </title>
      <simpara>Some text</simpara>
   </chapter>
   <chapter id="_title_three">
      <title>Title three<ulink url="http://bar.com "/>
      </title>
      <simpara>More text</simpara>
   </chapter>
</book>
person michael.hor257k    schedule 11.04.2015
comment
страхотно, благодаря ти. моето използване на въвеждане отразява опасностите от програмирането с копиране и поставяне - person DrTech; 12.04.2015

Тази кратка и пълна трансформация използва и отменя правилото за самоличност.

Имайте предвид, че не се използва <xsl:attribute> (наистина е ненужно):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ulink[. = 'Edit me']">
    <ulink role="{@role}" url="{preceding::processing-instruction('my_url')[1]}">
      <xsl:apply-templates/>
    </ulink>
  </xsl:template>
  <xsl:template match="processing-instruction()"/>
</xsl:stylesheet>

Когато тази трансформация се приложи към предоставения изходен XML документ:

<book lang="en">
    <bookinfo>
        <title>Title one</title>
    </bookinfo>
    <?my_url http://foo.com ?>
    <preface>
        <title>
            <ulink role="edit_me" url="test.asciidoc">Edit me</ulink>
        </title>
    </preface>
    <?my_url http://bar.com ?>
    <chapter id="_title_two">
        <title>Title two
            <ulink role="edit_me" url="test.asciidoc">Edit me</ulink>
        </title>
        <simpara>Some text</simpara>
    </chapter>
    <chapter id="_title_three">
        <title>Title three
            <ulink role="edit_me" url="test.asciidoc">Edit me</ulink>
        </title>
        <simpara>More text</simpara>
    </chapter>
</book>

Получава се желаният правилен резултат:

<book lang="en">
    <bookinfo>
        <title>Title one</title>
    </bookinfo>

    <preface>
        <title>
            <ulink role="edit_me" url="http://foo.com ">Edit me</ulink>
        </title>
    </preface>

    <chapter id="_title_two">
        <title>Title two
            <ulink role="edit_me" url="http://bar.com ">Edit me</ulink>
        </title>
        <simpara>Some text</simpara>
    </chapter>
    <chapter id="_title_three">
        <title>Title three
            <ulink role="edit_me" url="http://bar.com ">Edit me</ulink>
        </title>
        <simpara>More text</simpara>
    </chapter>
</book>
person Dimitre Novatchev    schedule 12.04.2015
comment
благодаря @dimitre. добро решение. всъщност трябваше да съхраня персонализирания URL адрес в променлива, за да мога да го използвам в клауза xsl:choose по-късно. - person DrTech; 12.04.2015