[英]XSL document() function not working when using a variable value in a predicate
我有2個xml文件:
我的目標是使用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.