根据我之前提出的一个问题,如何确保example/one/field
和example/three/field
包含在CDATA中,而example/two/field
则不包含?
输入:
<?xml version="1.0"?>
<example>
<one>
<field>CDATA required here</field>
</one>
<two>
<field>No CDATA thanks</field>
</two>
<three>
<field>More CDATA please</field>
</three>
</example>
所需输出:
<?xml version="1.0"?>
<example>
<one>
<field><![CDATA[CDATA required here]]></field>
</one>
<two>
<field>No CDATA thanks</field>
</two>
<three>
<field><![CDATA[More CDATA please]]></field>
</three>
</example>
我可以指定<xsl:output cdata-section-elements="field"/>
但这也会影响example/two/field
。我尝试输入类似 <xsl:output cdata-section-elements="example/one/field example/three/field"/>
的路径,但这会产生错误(错误 XTSE0280:元素名称无效。无效的 QName {example/one/field})。我哪里出错了?
使用您当前的标记,我认为 XSLT 没有一种干净的方法。至少需要使用不同的元素名称或不同的命名空间,以允许您和 XSLT 处理器的序列化程序区分哪些元素要输出为 CDATA 节,哪些元素不输出。
或者您需要考虑使用禁用输出转义,例如
<xsl:template match="one/field | three/field">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
[编辑]下面是一个完整的示例样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="one/field | three/field">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但请注意,禁用输出转义是一项可选的序列化功能,并非所有 XSLT 处理器都支持该功能。