2016-10-11 34 views
2

以下是使用XSLT和輸入/輸出XML。輸出XML包含空的CDATA元素。如何在不從cdata-section-elements中排除的情況下添加它? XSLT如何防止添加空的CDATA元素?

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output cdata-section-elements="first second" indent="yes"/> 
    <xsl:strip-space elements="first second"/> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

輸入

<?xml version="1.0" encoding="UTF-8"?> 
<top> 
    <first> 
     <second/> 
    </first> 
    <first> 
     <second><![CDATA[! Please note...]]></second> 
    </first> 
</top> 

輸出與帶狀空間

<?xml version="1.0" encoding="UTF-8"?> 
<top> 
    <first> 
     <second/> 
    </first> 
    <first> 
     <second><![CDATA[! Please note...]]></second> 
    </first> 
</top> 

不帶空間輸出

<?xml version="1.0" encoding="UTF-8"?> 
<top> 
    <first><![CDATA[ 
     ]]><second/><![CDATA[ 
    ]]></first> 
    <first><![CDATA[ 
     ]]><second><![CDATA[! Please note...]]></second><![CDATA[ 
    ]]></first> 
</top> 
+0

這是您期望的輸出,因爲您已將第一個元素指定爲CDATA節元素並且它具有子元素? –

+0

以上示例反映了真實文檔的結構和內容。第一個和第二個元素可能有一個CDATA部分。如果'first'或'second'包含CDATA,上述身份模板將按預期工作。在沒有CDATA的情況下,輸入XML也可能在'first'中嵌套'second'。我希望在應用身份模板時輸入與輸入相同。 – senleft

+0

我詢問了預期的輸出。如果您認爲XSLT中的標識轉換應該保留CDATA部分,那麼不會,XML會被XML解析器解析爲基於XSLT/XPath的樹模型,該模型只包含文本節點,而輸入樹是轉換成結果樹,如果使用'xsl:output cdata-section-elements'請求,某些元素的文本節點子元素可以被序列化爲CDATA節。但是,這是一個結果樹序列化步驟,然後將文本節點序列化爲CDATA節,它不依賴於輸入標記格式。 –

回答

1

關鍵字到該溶液中是function strip-space。來吧有:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output cdata-section-elements="first"/> 
    <xsl:strip-space elements="first second"/> 
    ... 

爲了有這兩個節點之間的空白文本節點精確:

<first> 
    <second/> 

CDATA不能忽視這些空格,否則它會改變的內容。所以你必須命令處理器,如何處理這些文本節點。


第二個可能的解決方案:你可以通過模板解決空白文本並刪除它們:

<xsl:template match="first/text()[not(normalize-space())]"/> 
0

我建議你試試這樣說:雖然我

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="second"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

因爲輸出與輸入相同 - 在語義上和詞彙上(除了可能的縮進量),都不太清楚這個練習的要點。