【问题标题】:How to get CDATA from xml node using xsl and convert in a new XML?如何使用 xsl 从 xml 节点获取 CDATA 并转换为新的 XML?
【发布时间】:2016-04-04 13:59:15
【问题描述】:

早安,

我对包含 CDATA 代码的 XML 有疑问。如果我们有这个 XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<character>
   <Body>
      <methodResult>
         <nodeOut>
            <![CDATA[  <film>Indiana Jones and the Kingdom of the Crystal Skull</film>]]>
         </nodeOut>
      </methodResult>
   </Body>
</character>

我们需要这个:

<film>Indiana Jones and the Kingdom of the Crystal Skull</film>

XSLT 在哪里?我只想提取 XML 文件中的 CDATA 内容并删除其余部分。我使用 XSLT 1.0。

谢谢!

【问题讨论】:

    标签: xml xslt cdata


    【解决方案1】:

    这将产生 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="2.0">
    
        <!-- ignore this elements -->
        <xsl:template match="role|actor|part"/>
    
        <!-- get the remaining text and remove white-spaces -->
        <xsl:template match="text()">
            <xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/>
        </xsl:template>
    
    </xsl:stylesheet>
    

    输出:

    <?xml version="1.0" encoding="UTF-8"?><film>Indiana Jones and the Kingdom of the Crystal Skull</film>
    

    【讨论】:

    • 您好 Baderous,此解决方案适用于 XSLT 2.0?我需要 XSLT 1.0。谢谢。
    • 虽然模板中写的是 2.0,但它是向后兼容的,因为它只使用了 1.0 的特性。
    • 我已经编辑了我的示例 xml...您可以查看它吗?非常抱歉,非常感谢。
    • 结果是一样的。你为什么不先测试一下?使用 Oxygen 之类的东西来创建 XSLT 并将转换应用于 XML。
    • 我用freeformatter.com/xsl-transformer.html 测试,但不起作用。谢谢你。
    【解决方案2】:

    您可以使用将输出方法设置为text 的转换,然后简单地从name 元素中提取文本节点。

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="text" />
    
        <xsl:template match="node()|@*">
            <xsl:apply-templates select="node()|@*" />
        </xsl:template>
    
        <xsl:template select="name/text()">
            <xsl:value-of select="." />
        </xsl:template>
    
    </xsl:stylesheet>
    

    请注意,如果元素中有多个 CDATA 部分,这将失败,如果输入中有多个 name,则需要创建某种根元素。您的 CDATA 部分中还有前导空格,所以我建议您修剪输出。您可以在 XSLT 本身中执行此操作的一种方法是使用函数normalize-space(),但它也会影响 CDATA“xml”的内容。此方法也没有 XML 序言,因此输出是否被视为有效 XML 取决于您将其提供给什么。

    但这是一个很好的起点。

    【讨论】:

    • 感谢 G_H,但我需要一个 XML 作为输出方法。这个解决方案对我无效:(我需要:
    【解决方案3】:

    在 XSLT 3.0(由 Saxon 9.7 或 Exselt 支持)中使用

    可以提供干净的解决方案
    <xsl:template match="/">
      <xsl:copy-of select="parse-xml-fragment(character/name/text()[last()])"/>
    </xsl:template>
    

    https://www.w3.org/TR/xpath-functions-30/#func-parse-xml-fragment

    【讨论】:

    • 抱歉,我忘记评论我使用的是 XSLT 1.0。谢谢
    猜你喜欢
    • 2011-02-27
    • 2013-09-07
    • 1970-01-01
    • 2021-02-28
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    相关资源
    最近更新 更多