繁体   English   中英

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

[英]XSL document() function not working when using a variable value in a predicate

我有2个xml文件:

  1. 包含小型内嵌img的技术文章
  2. 一个文件,除其他外,包含img,这些img是文章中小图像的完整版本。 我将这个文件称为“副文件”。

我的目标是使用xsl更新文章中的xml,以便为每个图添加一个img,而不是每个图一个img,而最初在文章xml中编码的是一个小img,而对应的较大的是一个。 这两个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将在覆盖图中可用。

问题描述:每篇文章可以包含许多图像。 每个辅助文件可以包含许多图像。 我必须将副文件中的正确图像与文章文件中的图像进行匹配。 我正在使用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:

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

您做错的第一件事就是尝试通过偏移量链接事物-五十年来众所周知,这是实现链接的最简单形式,也是最脆弱和容易出错的链接。 每当发生任何更改时,它都会中断,并且当它中断时,它会默默地中断,这确实很危险。 它只是在自找麻烦; 不要做 (看到这里的伤疤?那里的伤疤?我让那些人试图可靠地使基于偏移的链接工作。从我的悲伤和眼泪中学习!)

如果(如您的示例中),小图像和大图像具有相同的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" .../> -因此,如果您的主文档中的所有数字都是兄弟姐妹,它应该可以正常工作。 (这意味着您有一篇技术文章,其中包含14个数字,没有任何节。请告诉我,事实并非如此。)如果您想要数字的运行序列号,则需要类似<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 

这意味着谓词中的隐式position()将按其父级的图形子级的顺序获得图形的位置,而不是其在文档节点的图形后代中的位置。

由于同事的非常简单的建议,问题得以解决并得以解决。

$ 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]" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM