2012-12-06 33 views
1

我有一個xml文檔,其結構如下。我正在編寫一個轉換,我想從節點B輸出文本,但忽略元素C和文本節點「title」。從本質上講,我想提取文本「text goes here」並將其輸出到一個新的元素中,並將所有空白標準化。任何人都可以幫忙嗎?下面是我到目前爲止嘗試過的。XSLT:僅輸出當前節點的文本並標準化空白

Input Doc 
<A> 
    <B> 
    <C>title</C> 
    text goes here 
    </B> 
</A> 

Required output doc 
<d>text goes here</d> 


Solution A: 
<xsl:template match="B"> 
    <d>  
    <xsl:copy-of select="./text()"/>     
    </d> 
</xsl:template> 

問題:元素之間的空白被保留,所以我得到這樣的:

<d> 

    Text goes here 

</d> 

我在溶液中使用的儲值-的模板聲明(<xsl:value-of select="./text()"/>),但這沒還試圖根本不返回任何文字。聲明有什麼問題嗎?

我應該提到,我用下面覆蓋了默認的文本處理模板:<xsl:template match="text()" />

感謝

回答

4

原因<xsl:value-of select="./text()"/>返回「什麼都沒有「./text()將返回一個節點集合由當前節點的所有直接子文本節點組成。 value-of節點集是其第一個項的字符串值,在這種情況下,該項是開頭<B>和開頭<C>標籤之間的空白文本節點。這同樣適用於下一個最明顯的normalize-space(text()),因爲它再次將節點集轉換爲字符串(第一個節點值),然後規範化該字符串中的空間。相反,你需要單獨歸各子文本節點:

<d> 
    <xsl:for-each select="text()"> 
    <xsl:value-of select="normalize-space(.)"/> 
    </xsl:for-each> 
</d> 

有一點需要注意這雖然是,如果你有一個像

<A> 
    <B> 
    <C>title</C> 
    text goes here 
    <C>subtitle</C> 
    more text here 
    </B> 
</A> 

輸入,那麼你將得到的

<d>text goes heremore text here</d> 
輸出

字幕兩邊的位之間沒有空格。如果這是一個問題,你可以使用一招類似

<d> 
    <xsl:for-each select="text()[normalize-space(.)]"> 
    <xsl:if test="position() &gt; 1"><xsl:text> </xsl:text></xsl:if> 
    <xsl:value-of select="normalize-space(.)"/> 
    </xsl:for-each> 
</d> 

遍歷只包含非空格字符的文本節點孩子,和所有,但他們的第一個前添加一個空格。

<d>text goes here more text here</d> 
0

我得到的最接近的是有選擇的the child axis//B/child::text()

child軸將僅返回當前上下文節點的直接子節點的文本節點,因此它不會與title節點匹配。

+0

嘿,弗蘭克!你能否發佈完整的工作代碼?我試着用'B/child :: text()'和'value-of select =「normalize-space(。)」'和其他組合,但似乎它不適用於我.. –

+0

我無法得到這也可以工作。完整的模板將會有所幫助。謝謝 – JimS

0

試試這個代碼!

而不是使用<copy-of>我已經使用模板覆蓋!

  1. 我由d取代乙..

  2. 我滴<C>從輸出。這解決了一半的問題,因此<C>節點的文本不會出現在輸出中。

  3. 我申請正常化空間功能,所有文本節點..所以額外的空格將被抹去:)

這裏是代碼:

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output method="xml" indent="yes"/> 
     <xsl:template match="B"> 
     <d> 
      <xsl:apply-templates select="node()"/> 
     </d> 
     </xsl:template> 

     <xsl:template match="C"/> 

     <xsl:template match="text()"> 
     <xsl:value-of select="normalize-space(.)"/> 
     </xsl:template> 
    </xsl:stylesheet>