我正在尝试使用XSL获取XML节点的CDATA
内容。该
节点目前看起来像这样:
<node id="1" text="Book Information" ><![CDATA[This is sample text]]></node>
我需要This is sample text
件。有没有人对此有任何想法?
提前致谢。
答案 0 :(得分:10)
好吧,如果我使用这个样式表:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="node/text()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
在这个XML文件上:
<?xml version="1.0" encoding="utf-8"?>
<node id=1 text="Book Information" ><![CDATA[This is sample text]]></node>
我得到一个解析错误,因为id=1
是无效的XML。
在属性值(id="1"
)周围加上引号并重新运行样式表,我得到输出:
这是示例文本
所以有一个开始。基本上,只需将CDATA视为文本节点,即可开始使用。
你说:
我找到了类似的东西:
<xsl:output cdata-section-elements="text"/>
然后获取CDATA:
<xsl:value-of select="node" />
如果你也使用value-of
,这种方法也可以。以下是评论中的示例,使用value-of
代替。但请注意,cdata-section-elements
仅适用于输出端,指示要将哪些输出 XML元素打印为CDATA部分而不是普通的旧字符数据。它与获取数据没有任何关系。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output cdata-section-elements="foo"/>
<xsl:template match="/">
<foo>
<xsl:value-of select="node"/>
</foo>
</xsl:template>
</xsl:stylesheet>
打印出来
<?xml version="1.0"?>
<foo><![CDATA[This is sample text]]></foo>
答案 1 :(得分:1)
实现这一目标的其他一些简单步骤;
使用W3cschools编辑器试用。
XML文件示例:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<disk id="title"><![CDATA[Sample xml]]></disk >
<disk id="artist"><![CDATA[Vijay]]></disk >
</cd>
</catalog>
示例XSL文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="/catalog/cd/disk[@id='title']"/></td>
<td><xsl:value-of select="/catalog/cd/disk[@id='artist']"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
最终结果是;
答案 2 :(得分:0)
输出CDATA部分:
您必须使用xsl:output/@cdata-section-elements
。来自http://www.w3.org/TR/xslt#output
cdata-section-elements属性 包含以空格分隔的列表 QNames每个QName都扩展为 使用命名空间的扩展名 有效的声明 xsl:QName中的输出元素 发生;如果有默认值 命名空间,它用于QNames 没有前缀。扩张是 在合并之前执行 多个xsl:输出元素成一个 单个有效的xsl:output元素。 如果是父的扩展名 文本节点是列表的成员, 那么文本节点应该输出为 CDATA部分。
除了DOE之外,当然。
您无法使用XPath选择CDATA部分。根据{{3}}
有七种类型的节点:
根节点
元素节点
文本节点
属性节点
命名空间节点
处理指令节点
评论节点
来自http://www.w3.org/TR/xpath/#data-model
CDATA部分中的每个字符 被视为字符数据。从而, 源文档中的
<![CDATA[<]]>
将被视为&lt;。都 将导致单个&lt;中的人物 树中的文本节点。因此,一个CDATA 部分被视为<![CDATA[
并且]]>
被删除了<
和&
的出现被替换为 <{1}}和<
。
答案 3 :(得分:0)
我在网络上找到的唯一解决方案是 -
{XSLT}
<title>
<xsl:text disable-output-escaping="yes"><![CDATA[ <![CDATA[ ]]></xsl:text>
<xsl:value-of select="label" disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[]]]]><![CDATA[>]]></xsl:text>
</title>
但是,这不是最干净的解决方案,特别是如果您需要在XSLT的各个部分实现它。此外,如果您的输入XML已经具有CDATA(即您试图保留CDATA),则使用disable-output-escaping将无法工作,因为到那时CDATA已经被XSLT引擎解析,所有这些都将留下是最终会打破xml的内容。
这是我的解决方案 -
根据您使用XSLT的方式,可以使用外部/注入功能。这样做可以轻松地减少您正在编写的代码量,最终得到一个更清晰的模板:
{C#}
public string CDATAWrap(string data)
{
return "<![CDATA[" + data + "]]>";
}
{XSLT}
<title>
<xsl:value-of select="CDataType:CDATAWrap(label)" disable-output-escaping="yes" />
</title>
答案 4 :(得分:-1)
我尝试了各种组合,并为此得到了解决方案;
<xsl:value-of select="/node/."/>