简体   繁体   English

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

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

I have 2 xml documents: 我有2个xml文件:

  1. A technical article containing small inline img's 包含小型内嵌img的技术文章
  2. A file containing, among other things, img's that are full-size versions of the small images in the article. 一个文件,除其他外,包含img,这些img是文章中小图像的完整版本。 I'll call this file a "side file". 我将这个文件称为“副文件”。

My goal is to use xsl to update the xml in the article so that, instead of having one img for each figure, I have 2 img's ... the small one originally coded in the article xml, and the corresponding larger one. 我的目标是使用xsl更新文章中的xml,以便为每个图添加一个img,而不是每个图一个img,而最初在文章xml中编码的是一个小img,而对应的较大的是一个。 Both of these img's will be children of a new element, image-set. 这两个img都是新元素(图像集)的子元素。

So here's the 'Before' and 'After' situation: 因此,这是“之前”和“之后”的情况:

Before: 之前:

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

After: 后:

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

Another XSL will transform the updated article XML file into HTML. 另一个XSL将更新的文章XML文件转换为HTML。 The smaller img will be displayed inline as before, but the larger img will be available in an overlay when the user clicks a "See full-size version" link. 较小的img将像以前一样内联显示,但是当用户单击“查看完整版本”链接时,较大的img将在覆盖图中可用。

Problem description: Each article can contain many images. 问题描述:每篇文章可以包含许多图像。 Each side file can contain many images. 每个辅助文件可以包含许多图像。 I have to match up the right image in the side file with the image in the article file. 我必须将副文件中的正确图像与文章文件中的图像进行匹配。 I'm creating a variable using xsl:number to store, for each img, a number that corresponds to the order in which each image appears in the article file, and I'm trying to reference that variable in the document() function as a predicate to get the right img in the side file. 我正在使用xsl:number创建一个变量,以便为每个img存储一个数字,该数字对应于每个图像在文章文件中出现的顺序,并且我试图在document()函数中引用该变量,如下所示:在边文件中获取正确的img的谓词。 It's not working: 它不起作用:

Here's the variable for storing the order: 这是用于存储订单的变量:

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

Here's the code with the document() function that's not working with the 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>

When I run this, instead of getting just the img I want from the side file (in the example above, I should be getting just the first image, or img[1]), I get all the img's in the side file: 当我运行此文件时,我不只是从边文件中获取想要的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>

However, when I hard-code a predicate in the document() function, I get only the correct img (as in my "After" example above): 但是,当我在document()函数中对谓语进行硬编码时,只能得到正确的img(如上面的“ After”示例中所示):

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

I'm using oXygen 14.2 and have tried this transform with both XALAN and SAXON with the same results. 我使用的是oXygen 14.2,并尝试使用XALAN和SAXON进行此转换,结果相同。

What am I doing wrong? 我究竟做错了什么?

19 Aug 2013 update: 2013年8月19日更新:

I have since tried an alternate method of getting to the correct in the sidefile, but again no luck in getting the document() function to work with a variable inside it. 从那以后,我尝试了一种在sidefile中获取正确方法的替代方法,但是再次使document()函数与其中的变量一起工作并不幸运。 As in my previous method (using offsets), when I replace the variable in the document() function with a literal, it works. 与我以前的方法(使用偏移量)一样,当我用文字替换document()函数中的变量时,它可以工作。

This works: 这有效:

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

This doesn't: 这不是:

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

The $figureRef variable is defined as follows: With the pointer at a figure element in the article file, grab the string after the '#' in the @href value of the first anchor following the figure; $ figureRef变量的定义如下:将指针指向文章文件中某个图形元素,在该图形之后的第一个锚点的@href值中的'#'之后抓取字符串; then, surround it with single quotes: 然后,用单引号引起来:

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

Here's an xml snippet from the article file showing these elements: 这是文章文件中的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>

...and I know the figureRef variable is resolving to the correct value for each figure in the article because I'm adding xsl:comment's right before the document function to verify that its value is what it should be: ...而且我知道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>

...and you can see that it's correct from the result document snippet below (which should have another img element after the first): ...并且您可以从下面的结果文档摘要中看到正确的信息(在第一个之后应该有另一个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>

Sheesh. 啧。 Here is an xml snippet showing the structure of the side file: 这是一个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>

The first thing you're doing wrong is trying to link things by offsets -- well known for fifty years or so as the simplest form of linking to implement and the most fragile and error prone. 您做错的第一件事就是尝试通过偏移量链接事物-五十年来众所周知,这是实现链接的最简单形式,也是最脆弱和容易出错的链接。 It breaks any time anything changes, and when it breaks, it breaks silently , which makes it really dangerous. 每当发生任何更改时,它都会中断,并且当它中断时,它会默默地中断,这确实很危险。 It's just asking for trouble; 它只是在自找麻烦; don't do it. 不要做 (See this scar here? and that one there? I got those trying to make offset-based linking work reliably. Learn from my sorrow and tears!) (看到这里的伤疤?那里的伤疤?我让那些人试图可靠地使基于偏移的链接工作。从我的悲伤和眼泪中学习!)

If (as in your example), the small and large image have the same alt attribute and the image file names are systematically related, you would get better results with something like 如果(如您的示例中),小图像和大图像具有相同的alt属性,并且图像文件名是系统相关的,则使用类似以下内容可获得更好的结果

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

Optionally, do a sanity check on the file names: (可选)对文件名进行完整性检查:

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

However, if your main file and your side file really do reliably have the small and large images in the same sequence, the approach you are attempting can be made to work. 但是,如果您的主文件和副文件确实确实具有相同大小的图像,则可以使您尝试的方法起作用。 (At least, up until the first time anything in either document changes the order or number of figures.) Since you show very little of your main file and nothing of your side file, it's hard to know exactly what is going wrong with your code, but there are some obvious things to check: (至少,直到第一次,任何一个文档中的任何内容都更改了顺序或图形数量。)由于您只显示了很少的主文件,而没有显示辅助文件,因此很难确切知道代码出了什么问题,但要检查一些明显的事情:

  • <xsl:number/> defaults to <xsl:number level="single" .../> -- so it should work fine if all the figures in your main document are siblings. <xsl:number/>默认为<xsl:number level="single" .../> -因此,如果您的主文档中的所有数字都是兄弟姐妹,它应该可以正常工作。 (That would mean you have a technical article with fourteen figures and no sections. Please tell me that's not so.) If you want a running sequence number for figures, you want something like <xsl:number level="any"/> -- I think some XSLT coders would write <xsl:variable name="figureNumber" select="1 + count(preceeding::figure)"/> instead. (这意味着您有一篇技术文章,其中包含14个数字,没有任何节。请告诉我,事实并非如此。)如果您想要数字的运行序列号,则需要类似<xsl:number level="any"/> - -我认为某些XSLT编码人员会改写<xsl:variable name="figureNumber" select="1 + count(preceeding::figure)"/>
  • The fact that you write document('sidefile.xml',/)//figure ... suggests that the figure elements in the side document may be at any depth, and not necessarily all siblings; 您编写document('sidefile.xml',/)//figure ...的事实表明,副文档中的图形元素可能在任何深度,而不一定是所有同级。 if that's so, selecting them by [$figureNumer] is never going to work. 如果是这样,则通过[$figureNumer]选择它们永远不会起作用。 Recall that // expands to /descendant-or-self::*/, so your expression expands to 回想一下//扩展为/ descendant-or-self :: * /,因此您的表达式扩展为

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

which means that the implicit position() in the predicate will get the figure's position in the sequence of its parent's figure children, not its position among the figure descendants of the document node. 这意味着谓词中的隐式position()将按其父级的图形子级的顺序获得图形的位置,而不是其在文档节点的图形后代中的位置。

Problem identified and fixed, thanks to a colleague's very simple suggestion. 由于同事的非常简单的建议,问题得以解决并得以解决。

The $figureRef variable is already a string value, so no need to surround it with single quotes. $ figureRef变量已经是一个字符串值,因此无需将其用单引号引起来。 Adding the quotes ensured I'd never get the result set I needed. 添加引号可确保我永远不会得到所需的结果集。 So.... 所以....

Before: 之前:

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

After: 后:

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

Using it in the document() function: 在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