说我有一个XML文件,如:
<library>
<books>
<![CDATA[<genre><name>Sci-fi</name><count>2</count></genre>]]>
<book>
<name>
Some Book
</name>
<author>
Some author
</author>
<book>
<book>
<name>
Another Book
</name>
<author>
Another author
</author>
<book>
<books>
</library>
我想在xslt转换器中读取CDATA元素'name',并将其值放在标签的vaue中。我该怎么做呢? AFAIK,我们不能在CDATA的内容上使用xpath。这有什么黑客/解决方法吗?我想在XSLT中严格执行此操作。
答案 0 :(得分:6)
某些XSLT产品具有扩展功能,例如saxon:parse(),它允许您获取包含词法XML的字符串并将其转换为节点树。
答案 1 :(得分:4)
您还可以选择CDATA部分,然后将结果传递给第二个XSL。
例如,如果您按照以下方式获得CDATA部分:
<xsl:template match="//books/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
你最终会得到如下结果:
<genre><name>Sci-fi</name><count>2</count></genre>
然后你可以应用另一个XSL,或XPATH如果只处理一个DOM。假设您的CDATA始终是有效的XML。否则,马丁的RegEx答案就是这样。
答案 2 :(得分:3)
由于CDATA块是(部分)文本节点,因此您可以在两个“标记”之间提取文本,例如像这样:
<xsl:template match="text()">
<xsl:value-of select="substring-before(substring-after(., '<name>'), '</name>')"/>
</xsl:template>
这只是一个简单的想法。如果CDATA中有多个名称“element”,则只需递归地多次应用上述表达式。
答案 3 :(得分:1)
也许我的回答太晚了,但无论如何我都会给它。 我遇到了同样的问题,找不到一个易于使用的答案,所以我自己写了一个模板“STR2XML”来做这件事。如果有人有兴趣,我很乐意分享模板。请告诉我。
两个如何运作的例子:
<xsl:variable name="text">
<![CDATA[
<div style="color:red;">
<p>hello world</p>
</div>
]]>
</xsl:variable>
<p>
<xsl:value-of select="$text"/>
</p>
<xsl:call-template name="str2xml">
<xsl:with-param name="text" select="$text"/>
</xsl:call-template>
将提供以下输出:
<div style="font-weight:bold;"> <p>hello world</p> </div> (non parsed plain text)
你好世界
但是当然你也可以使用它来创建一个可以作为节点访问的变量:
<xsl:variable name="text2">
<![CDATA[
<div>hello world</div>
<p>goodbye world</p>
]]>
</xsl:variable>
<xsl:variable name="var1">
<xsl:call-template name="str2xml">
<xsl:with-param name="text" select="$text2"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="xalan:nodeset($var1)/*">
<p>
<xsl:value-of select="concat(name(.),': ',.)"/>
</p>
</xsl:for-each>
输出:
div:你好世界
p:再见世界