使用处理指令在XSLT中设置变量

时间:2015-04-11 17:58:24

标签: xslt docbook

我在docbook后端使用asciidoc,并且我尝试将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:&#34;找到前面的处理指令my_url并使用其内容来设置值变量&#34;

按照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

2 个答案:

答案 0 :(得分:1)

您正在使用:

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>

答案 1 :(得分:1)

此简短而完整的转换使用并覆盖了身份规则

请注意没有使用<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>