在谓词中使用变量值时,XSL document()函数不起作用

时间:2013-08-16 16:12:33

标签: variables xslt document predicate

我有2个xml文档:

  1. 包含小型内联img的技术文章
  2. 一个文件,其中包含文章中小图像的完整版本的img。我将此文件称为“副文件”。
  3. 我的目标是使用xsl来更新文章中的xml,这样我就不再拥有每个图形的一个img,而是有2个img ...原来在文章xml中编写的小版本,以及相应的较大版本。这两个img都将是一个新元素的图像集。

    所以这里是'之前'和'之后'的情况:

    在:

    <figure>
       <heading alttoc="" refname="fig1" type="figure">Figure 1. netserver on SUT in out
          of the box configuration</heading>
       <img alt="netserver on SUT in out-of-the-box configuration" 
            height="288" src="figure1.jpg" width="572"/>
    </figure>
    

    后:

    <figure>
       <heading alttoc="" refname="fig1" type="figure">Figure 1. netserver on SUT in out
          of the box configuration</heading>
             <image-set>
                    <img alt="netserver on SUT in out-of-the-box configuration" 
                         height="288" src="figure1.jpg" width="572"/>
                    <img alt="netserver on SUT in out-of-the-box configuration" 
                         height="456" src="figure1_ian.jpg" width="905"/>
             <!--The figureNumber is: 1-->
             </image-set>
    </figure>
    

    另一个XSL会将更新的文章XML文件转换为HTML。较小的img将像以前一样以内嵌方式显示,但当用户点击“查看完整版本”链接时,较大的img将以叠加方式显示。

    问题描述: 每篇文章都可以包含许多图片。每个边文件可以包含许多图像。我必须将side文件中的正确图像与文章文件中的图像进行匹配。我正在使用xsl:number创建一个变量,为每个img存储一个数字,该数字对应于每个图像在文章文件中出现的顺序,我试图在document()函数中引用该变量一个谓词,用于在副文件中获取正确的img。这不起作用:

    这是存储订单的变量:

    <xsl:variable name="figureNumber">
            <xsl:number />
    </xsl:variable>
    

    这是带有document()函数的代码,它不使用变量:

    <!-- Output the larger version of the same img that sits in the sidefile.
    The "/" as the second argument causes processor to look for the  sidefile 
    in same folder as the article xml file. -->
    <xsl:copy-of select="document('sidefile.xml',/)//figure[$figureNumber]/img" />
    <xsl:comment>The figureNumber is: <xsl:value-of select="$figureNumber"/></xsl:comment>
    

    当我运行它时,而不是从侧面文件中获取我想要的img(在上面的示例中,我应该只获得第一个图像,或img [1]),我得到了所有的img's在旁边文件:

    <figure>
      <heading alttoc="" refname="fig1" type="figure">Figure 1. netserver on SUT in out
        of the box configuration</heading>
      <image-set>
        <img alt="netserver on SUT in out-of-the-box configuration" 
             height="288" src="figure1.jpg" width="572"/>
        <img alt="netserver on SUT in out-of-the-box configuration" 
             height="456" src="figure1_ian.jpg" width="905"/>
        <img alt="netperf on SUT in out-of-the-box configuration" 
             height="456" src="figure2_ian.jpg" width="905"/>
        <img alt="netperf and netserver (bidirectional) on SUT out of the box" 
             height="456" src="figure3_ian.jpg" width="905"/>
        <img alt="netserver, out of the box with numactl" 
             height="456" src="figure4_ian.jpg" width="905"/>
        <img alt="netperf, out of the box with numactl" 
             height="456" src="figure5_ian.jpg" width="905"/>
        <img alt="netperf and netserver (bidirectional), out of the box with numactl" 
             height="456" src="figure6_ian.jpg" width="905"/>
        <img alt="netserver, Ethernet SMP IRQ affinity, no irqbalance" 
             height="456" src="figure7_ian.jpg" width="905"/>
        <img alt="netperf, Ethernet SMP IRQ affinity, no irqbalance" 
             height="456" src="figure8_ian.jpg" width="905"/>
        <img alt="netperf and netserver (bidirectional), Ethernet SMP IRQ affinity, no irqbalance" 
             height="456" src="figure9_ian.jpg" width="905"/>
        <img alt="netserver, Ethernet SMP IRQ affinity and numactl, no irqbalance" 
             height="456" src="figure10_ian.jpg" width="905"/>
        <img alt="netperf, Ethernet SMP IRQ affinity and numactl, no irqbalance" 
             height="456" src="figure11_ian.jpg" width="905"/>
        <img alt="Bidirectional,  Ethernet SMP IRQ affinity and numactl, no irqbalance" 
             height="456" src="figure12_ian.jpg" width="905"/>
        <img alt="netserver, Ethernet SMP IRQ affinity, no irqbalance, bonded interfaces" 
             height="456" src="figure13_ian.jpg" width="905"/>
        <img alt="netserver, Ethernet SMP IRQ affinity, no irqbalance, with and without bonding" 
             height="456" src="figure14_ian.jpg" width="905"/>
        <!--The figureNumber is: 1-->
      </image-set>
    </figure>
    

    但是,当我在document()函数中对谓词进行硬编码时,我只得到正确的img(如上面的“After”示例所示):

    <xsl:copy-of select="document('sidefile.xml',/)//figure[1]/img" />
    

    我正在使用oXygen 14.2并尝试使用XALAN和SAXON进行此转换,结果相同。

    我做错了什么?

    2013年8月19日更新:

    我已经尝试了另一种在sidefile中获取正确的方法,但是再次没有运气使document()函数处理其中的变量。正如我之前的方法(使用偏移),当我用文字替换document()函数中的变量时,它可以工作。

    这有效:

    <xsl:copy-of select="document('sidefile.xml',/)/dw-document/dw-sidefile/docbody/figure/img[preceding::heading[1]/@refname = 'fig1']" />
    

    这不是:

    <xsl:copy-of select="document('sidefile.xml',/)/dw-document/dw-sidefile/docbody/figure/img[preceding::heading[1]/@refname = $figureRef]" />
    

    $ figureRef变量定义如下:将指针放在文章文件中的一个数字元素上,抓住图后第一个锚点的@href值中的'#'后的字符串;然后,用单引号括起来:

    <xsl:variable name="figureRef" select="concat($singleQuote,substring-after(following::a[1]/@href,'#'),$singleQuote)"/>
    

    以下是文章文件中的xml片段,其中显示了以下元素:

    <figure>
        <heading alttoc="" refname="fig1" type="figure">Figure 1. netserver on SUT in out of the box configuration</heading>
    <img alt="netserver on SUT in out-of-the-box configuration" height="288" src="figure1.jpg" width="572"/>
    </figure>
    <p><b><a href="http://www.ibm.com/developerworks/library/l-scalability/sidefile.html#fig1">Enlarge Figure 1.</a></b></p>
    

    ...我知道figureRef变量正在解析文章中每个数字的正确值,因为我在文档函数之前添加了xsl:comment,以验证它的值是应该的:

    <xsl:when test="not(image-set)">
                <xsl:element name="figure">
                    <xsl:apply-templates select="heading" />
                    <xsl:element name="image-set">
                        <!-- Output the img element that was inside the original figure element -->
                        <xsl:apply-templates select="img" />
                        <!-- Output the larger version of the same img that sits in the
                            sidefile.  The "/" as the second argument causes processor to look for the
                            sidefile in same folder as the article xml file. -->
                        <xsl:comment>The figureRef is: <xsl:value-of select="$figureRef"/></xsl:comment>
                        <xsl:copy-of
                            select="document('sidefile.xml',/)/dw-document/dw-sidefile/docbody/figure/img[preceding::heading[1]/@refname = $figureRef]" />
                        <xsl:comment>The figureNumber is: <xsl:value-of select="$figureNumber"/></xsl:comment>                        
                    </xsl:element>
                </xsl:element>
            </xsl:when>
    

    ...你可以从下面的结果文档片段中看到它是正确的(在第一个之后应该有另一个img元素):

    <image-set>
        <img alt="netserver on SUT in out-of-the-box configuration" height="288" src="figure1.jpg" width="572"/>
        <!--The figureRef is: 'fig1'-->
        <!--The figureNumber is: 1-->
    </image-set>
    

    啧。这是一个xml片段,显示了辅助文件的结构:

    <figure>
        <heading alttoc="" refname="fig1" type="figure">Figure 1. netserver on SUT in out
          of the box configuration</heading>
        <img alt="netserver on SUT in out-of-the-box configuration" height="456" src="figure1_ian.jpg" width="905"/>
      </figure>
    
      <!-- Spacer  -->
      <br/>
      <br/>
      <!-- Return link -->
      <p>
        <a href="index.html#fig1">Return to article</a>
      </p>
      <!-- Spacer -->
      <br/>
    
      <figure>
        <heading alttoc="" refname="fig2" type="figure">Figure 2. netperf on SUT in out of
          the box configuration</heading>
        <img alt="netperf on SUT in out-of-the-box configuration" height="456" src="figure2_ian.jpg" width="905"/>
      </figure>
    

2 个答案:

答案 0 :(得分:1)

你做错的第一件事是尝试通过抵消来链接事物 - 众所周知的是50年左右的最简单形式的链接实现和最脆弱和容易出错。它会在任何时候发生变化时中断,当它发生故障时,它会静静地 ,这会让它变得非常危险。这只是在寻找麻烦;不要这样做。 (在这里看到这个伤痕?那里有那个伤痕?我让那些试图让基于偏移的连接工作可靠地工作。从我的悲伤和泪水中学习!)

如果(如您的示例中),小图像和大图像具有相同的alt属性,并且图像文件名称系统相关,则可以使用类似

的结果获得更好的结果
<xsl:variable name="alt" select="@alt"/>
<xsl:copy-of select="document('side-file.xml',/)
                     //img[@alt = $alt]"/>

(可选)对文件名进行健全性检查:

<xsl:variable name="fn-small" select="@src"/>
<xsl:variable name="fn-big" 
              select="document('side-file.xml',/)
                     //img[@alt = $alt]/
                     @src"/>
<xsl:if test="substring-before($fn-small,'.jpg')
             != substring-before($fn-big,'_ian.jpg')">
  <xsl:message>Problems with image <xsl:value-of 
    select="concat($fn-small, ' / ', $fn-big)"/>.</xsl:message>
</xsl:if>

但是,如果您的主文件和副文件确实可靠地以相同的顺序显示小图像和大图像,则可以使您尝试的方法起作用。 (至少,直到第一次任何一个文档中的任何内容改变了数字的顺序或数量。)由于你显示的主文件很少而且你的副文件没有任何内容,所以很难确切地知道代码出了什么问题。 ,但有一些明显的事情需要检查:

  • <xsl:number/>默认为<xsl:number level="single" .../> - 所以如果主文档中的所有数字都是兄弟姐妹,它应该可以正常工作。 (这意味着你有一篇技术文章有十四个数字,没有任何部分。请告诉我并非如此。)如果你想要一个数字的运行序列号,你需要类似<xsl:number level="any"/>的东西 - 我认为一些XSLT编码器会改为写<xsl:variable name="figureNumber" select="1 + count(preceeding::figure)"/>
  • 你写document('sidefile.xml',/)//figure ...的事实表明,侧面文件中的数字元素可能处于任何深度,而不一定是所有兄弟姐妹;如果是这样的话,那么通过[$figureNumer]选择它们永远不会起作用。回想一下//扩展为/ descendant-or-self :: * /,因此表达式扩展为

    document('sidefile.xml',/)
      /descendant-or-self::*
      /child::figure[position() = $figureNumber]
      /img
    

这意味着谓词中的隐含位置()将获得图形在其父图形子元素序列中的位置,而不是它在文档节点的图形后代中的位置。

答案 1 :(得分:0)

由于同事非常简单的建议,确定并修复了问题。

$ figureRef变量已经是一个字符串值,所以不需要用单引号括起来。添加引号确保我永远不会得到我需要的结果集。所以....

<强>之前:

<xsl:variable name="figureRef" select="concat($singleQuote,substring-after(following::a[1]/@href,'#'),$singleQuote)"/>

<强>后:

<xsl:variable name="figureRef"><xsl:value-of select="substring-after(following::a[1]/@href,'#')"/></xsl:variable>

在document()函数中使用它:

<xsl:copy-of select="document('sidefile.xml',/)/dw-document/dw-sidefile/docbody/figure/img[preceding::heading[1]/@refname = $figureRef]" />