0

从我问的上一个问题分叉出来,我如何确保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: Invalid element name. Invalid QName {example/one/field})。我哪里错了?

4

1 回答 1

2

使用您当前的标记,我认为 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>

但是请注意,disable-output-escaping 是一种可选的序列化功能,并非所有 XSLT 处理器都支持。

于 2012-05-28T10:07:19.053 回答