2010-05-06 105 views
2

我如何選擇一個文本節點的前面節點,從一個特定的節點開始,這個節點的id是我知道的,而不是從根節點獲取文本節點?如何從特定節點開始選擇文本節點的前節點而不是根節點?

當我從文本節點的模板匹配中調用下面的塊時,我從根目錄獲取所有前面的文本節點。我想修改上面的代碼只選擇後出現具有特定ID的節點說123即像文本節點// * [@ ID =「123」]

  <xsl:template match="text()[. is $text-to-split]"> 
      <xsl:variable name="split-index" as="xsd:integer" 
      select="$index - sum(preceding::text()/string-length(.))"/> 
      <xsl:value-of select="substring(., 1, $split-index - 1)"/> 
      <xsl:copy-of select="$new"/> 
      <xsl:value-of select="substring(., $split-index)"/> 
      </xsl:template> 

     <xsl:variable name="text-to-split" as="text()?" 
     select="descendant::text()[sum((preceding::text(), .)/string-length(.)) ge $index][1]"/> 

怎麼辦我將條件包括在我使用的前面:: text的位置,以便選擇與我知道的特定節點的ID相關的前面的文本節點?

+0

好問題(+1)。看到我的答案有三種不同的解決方案:) – 2010-05-06 18:54:02

+0

@DimitreNovatchev你忘了實際+1嗎? ;) – Izkata 2013-10-08 18:59:21

+0

從我+1,因爲這個問題已經給出瞭如何解決我自己的問題的想法... – Izkata 2013-10-08 19:12:51

回答

1

下面是您可以使用幾個變種:​​

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:strip-space elements="*"/> 
<xsl:output method="text"/> 

<xsl:variable name="vStart" select="/*/*[@myId='123']/text()"/> 
<xsl:variable name="vEnd" select="/*/*[last()]"/> 

    <xsl:template match="/"> 
     <xsl:value-of select= 
     "*/*[last()] 
      /sum(preceding::text() 
       intersect 
        $vStart/following::text() 
       ) 
    "/> 
--------------- 
     <xsl:value-of select= 
     "*/*[last()] 
      /sum(preceding::text()[. >> $vStart]) 
    "/> 
--------------- 
     <xsl:value-of select= 
     "sum(/*/*[. >> $vStart and . &lt;&lt; $vEnd]) 
    "/> 
    </xsl:template> 
</xsl:stylesheet> 

當下面的XML文檔應用這種轉變:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num myId='123'>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>010</num> 
</nums> 

預期的結果產生

30 
--------------- 
     30 
--------------- 
     30 
+0

這太好了。謝謝。我使用normalize-space(),而我發現文本內容的長度,以便標籤之間沒有額外的空間計數,但如果我有xhtml中的選項卡空間它會得到計數。我如何忽略它。即使我使用帶區,它也會被計數。就像我添加一個謂詞來標準化空間一樣,我可以添加一個謂詞來忽略標籤空間,而我計算文本內容的長度。如何做呢? – Rachel 2010-05-06 21:04:37

+0

@Rachel:使用:'translate($ yourText,' ','') – 2010-05-07 01:37:49

1

在XPath 2.0中,可以使用運算符<<>>來比較節點排序。例如:

preceding-sibling::text()[. >> $foo] 

將選擇在當前之前的所有兄弟文本節點,隨後按文檔順序節點$foo。當然,您可以使用表達式而不是$foo - 就您的情況而言,//*[@id='123'] - 雖然將其綁定到變量,然後在過濾器中使用它可能更容易使XSLT處理器優化。

請參閱this瞭解這些操作員的詳細規範。

+0

我使用normalize-space()時,我發現文本內容的長度,以便標記之間沒有額外的空間計數,但如果我在xhtml中有標籤空間它會被計算。我如何忽略它。即使我使用帶區,它也會被計數。就像我添加一個謂詞來標準化空間一樣,我可以添加一個謂詞來忽略標籤空間,而我計算文本內容的長度。如何做呢? – Rachel 2010-05-06 21:23:45

+0

你能舉出暴露你的問題的示例XML輸入,並突出顯示你想剝離的空白節點嗎? – 2010-05-07 02:19:46

+0

有沒有在XPath 1.0中完成此操作的方法?我在這裏發佈了一個類似的問題:http://stackoverflow.com/q/11037979/107277 – 2012-06-14 17:09:00

相關問題