将某些字段包装在 CDATA 中,但不包装其他同名字段

  • 本文关键字:包装 字段 其他 CDATA xslt
  • 更新时间 :
  • 英文 :


根据我之前提出的一个问题,如何确保example/one/fieldexample/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">]]&gt;</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">]]&gt;</xsl:text>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

但请注意,禁用输出转义是一项可选的序列化功能,并非所有 XSLT 处理器都支持该功能。

最新更新