我正在尝试将包含以下内容的文档转换为另一个文档,使CDATA与第一个文档完全一样,但我还没有想出如何使用XSLT保留CDATA。
初始XML:
<node>
<subNode>
<![CDATA[ HI THERE ]]>
</subNode>
<subNode>
<![CDATA[ SOME TEXT ]]>
</subNode>
</node>
最终XML:
<newDoc>
<data>
<text>
<![CDATA[ HI THERE ]]>
</text>
<text>
<![CDATA[ SOME TEXT ]]>
</text>
</data>
</newDoc>
我尝试过类似的东西,但没有运气,一切都变得混乱:
<xsl:element name="subNode">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:element>
如何保存CDATA?
谢谢! 兰斯
使用ruby / nokogiri
更新:这是有效的。
<text disable-output-escaping="yes"><![CDATA[</text>
<value-of select="normalize-space(text())" disable-output-escaping="yes"/>
<text disable-output-escaping="yes">]]></text>
这将包装CDATA中的所有text()节点,这些节点适用于我需要的内容,并且它将在文本中保留html标签。
答案 0 :(得分:5)
如果CDATA节点与纯文本节点混合,则无法保留CDATA节点的精确序列。充其量,您可以通过在xsl:output/@cdata-section-elements
中列出该元素名称来强制输出中特定元素的所有内容:
<xsl:output cdata-section-elements="text"/>
答案 1 :(得分:3)
很抱歉发布我自己的问题的答案,但我找到了有效的方法:
<text disable-output-escaping="yes"><![CDATA[</text>
<value-of select="normalize-space(text())" disable-output-escaping="yes"/>
<text disable-output-escaping="yes">]]></text>
这将包装CDATA中的所有text()节点,这些节点适用于我需要的内容,并且它将在文本中保留html标签。
答案 2 :(得分:0)
我在尝试解决类似问题时找到了这篇文章(使用XSL转换来获取一个XML文件,并为其中的某些节点创建部分/子集副本,作为第二个XML文件)。在我的情况下,第一个XML文件包含一些值完全封装在CDATA块中的元素,因为它们恰好是JSON并且带有一些HTML格式标记。
我发现我可以使用UnwindPipe
而不是使用xsl:value-of
,就像@Pavel Minaev指出的那样,我可以通过在列表中列出每个相关元素的名称来保持原始CDATA的完整性。 xsl:输出声明。这可能是一种适用于OP的方法。
要复制的XML(示例):
xsl:copy-of
相关的样式表行:
<text_item>
<id>100</id>
<stem_text><![CDATA[(any string of text, including HTML)]]></stem_text>
<answerOptions><![CDATA[{"choices":[{"label":"Atmospheric O<sub>2</sub>",
"value":"A"},{"label":"Released CO<sub>2</sub>",
"value":"B"}]}]]></answerOptions>
...
</text_item>
<xsl:output method="xml" indent="yes" cdata-section-elements="stem_text answerOptions" />
...
<xsl:apply-templates select="//text_item" >
...
<xsl:template match="text_item">
<xsl:element name="text_item" >
<xsl:copy-of select="node()" />
</xsl:element>
</xsl:template>
属性意味着在输出中,当转换运行时,从 复制的XML中的原始CDATA块将按原样传递到输出XML文件。 。看来您可以根据需要命名任意多个元素。
在OP的示例中,我相信他会在cdata-section-elements
上进行选择,然后在//node/subNode
内建立一个名为text
的元素。就像帕维尔(Pavel)所言,他的newDoc/data
就是cdata-section-elements attribute
。