5

假设我有一个 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 元素“名称”,并将其值放在标记值的某个位置。我该怎么做呢?AFAIK,我们不能对 CDATA 的内容使用 xpath。是否有一些破解/解决方法?我想在 XSLT 中严格执行此操作。

4

4 回答 4

7

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

于 2012-04-26T08:24:05.120 回答
6

您还可以选择 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>

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

于 2012-04-25T21:32:27.127 回答
3

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

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

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

于 2012-04-25T20:51:54.243 回答
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:再见世界

于 2014-08-02T02:34:33.317 回答