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