如何防止添加空CDATA元素



下面使用XSLT和输入/输出XML。输出XML包含空的CDATA元素。如何防止添加它而不排除cdata-section-elements?XSLT

    <?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>

解决的关键字是函数条带空间。继续输入:

<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())]"/>

我建议你这样试试:

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

虽然我不太明白这个练习的意义,因为输出和输入是相同的——无论是语义上还是词法上(除了可能的缩进量)。

最新更新