2

摘要:我正在使用xslt转换数据,并且需要生成一些带有CDATA的标签和一些没有标签的标签。转义 CDATA 部分是我唯一的选择吗?

我正在尝试将 xml 中已有的数据转换为Moodle Xml以进行导入。最终产品需要包含一些 Html,Moodle Xml 文档特别指出需要包含在 CDATA 中。

期望的输出:

<question>
  <name>
    <text>FooName</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<img src="1.png">]]></text>
  </questiontext>
</question>

我使用以下代码进行了尝试(精简,但将包含来自我的输入 xml 文件的数据):

方法一,没什么特别的

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <question>
      <name>
        <text>FooName</text>
      </name>
      <questiontext format="html">
        <text><![CDATA[<img src="1.png">]]></text>
      </questiontext>
   </xsl:template>

</xsl:stylesheet>

并得到...

方法 1 的错误输出

<question>
  <name>
    <text>FooName</text>
  </name>
  <questiontext format="html">
    <text>&lt;img src="1.png"&gt;</text>
  </questiontext>
</question>

所以我查阅了xslt 文档一些 SO questions,这似乎说我有两个选择:

  1. 什么都不做,CDATA 被转义。
  2. 用于cdata-section-elements ="text"在标签内自动生成 cdata 部分
  3. 手动生成 CDATA 部分,使用disable-output-escaping="yes"

好的,自动生成听起来不错。让我们试试:

方法二添加cdata-section-elements="text"

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" cdata-section-elements="text"/>

错误输出cdata-section-elements ="text"

<question>
  <name>
    <text><![CDATA[FooName]]></text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<img src="1.png">]]></text>
  </questiontext>
</question>

所以 2 不是一个选项,因为在我无法控制的模式中,我不想包含 CDATA 的其他元素。

这给我留下了选项 3,手动逃脱它。那么我的问题是:选项 3 是我唯一的选择吗?我还能做些什么来使用 XSLT 获得我想要的输出吗?不使用 XSLT?

4

3 回答 3

5

我在http://neehouse.com/code/xslt/cdata_string_output.aspx上找到了这种方法

代码

<no1>
    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
    <xsl:value-of select="data/NO1"/>
    <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
</no1>

输出

<no1><![CDATA[xxxxxxxxxxxx]]></no1>
于 2011-08-16T14:38:09.517 回答
0

正如 Dimitre 回答的那样,您的要求很奇怪,因为在 XML 元素中,名称具有模式含义。如果text元素架构允许 CDATA,则所有text元素都是如此。

一种用额外元素做你想做的事情的方法:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:output cdata-section-elements="xhtml:div"/>
    <xsl:template match="/">
        <question>
            <name>
                <text>FooName</text>
            </name>
            <questiontext format="html">
                <text>
                     <xhtml:div><![CDATA[<img src="1.png">]]></xhtml:div>
                </text>
            </questiontext>
        </question>
    </xsl:template>
</xsl:stylesheet>

输出(任何输入):

<question xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <name>
        <text>FooName</text>
    </name>
    <questiontext format="html">
        <text>
            <xhtml:div><![CDATA[<img src="1.png">]]></xhtml:div>
        </text>
    </questiontext>
</question>
于 2010-08-31T14:40:49.440 回答
0

正如您所注意到的,您的方法 1 和方法 2 没有产生您想要的结果。

由于对输出词法外观的极其奇怪和罕见的要求,您只剩下第三种方法。

于 2010-08-31T03:06:00.957 回答