如何在XSLT中解析CDATA元素中的XML DOM?

r3s*_*0r3 5 xml xslt xpath cdata

说我有一个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>
Run Code Online (Sandbox Code Playgroud)

我想在xslt转换器中读取CDATA元素'name',并将其值放在标签的vaue中.我该怎么做呢?AFAIK,我们不能在CDATA的内容上使用xpath.这有什么黑客/解决方法吗?我想在XSLT中严格执行此操作.

Jay*_*zen 6

您还可以选择 CDATA 部分,然后将结果传递给第二个 XSL。

例如,如果您像这样获取 CDATA 部分:

<xsl:template match="//books/text()">
  <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

你最终会得到如下结果:

<genre><name>Sci-fi</name><count>2</count></genre>
Run Code Online (Sandbox Code Playgroud)

然后你可以应用另一个 XSL,或者 XPATH,如果只处理一个 DOM。那是假设您的 CDATA 始终是有效的 XML。否则,马丁的 RegEx 答案就是这样。


Mic*_*Kay 6

一些XSLT产品具有扩展函数,例如saxon:parse(),它允许您获取包含词法XML的字符串并将其转换为节点树.


Mar*_*tin 4

由于 CDATA 块是文本节点(的一部分),因此您可以提取两个“标签”之间的文本,例如:

<xsl:template match="text()">
  <xsl:value-of select="substring-before(substring-after(., '&lt;name>'), '&lt;/name>')"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

这只是一个快速的想法。如果 CDATA 中有多个名称“元素”,只需多次递归应用上述表达式即可。