xslt - 关于 XSLT 的问题,以消除子节点位于 CDATA 部分的父节点

标签 xslt

我有一个原始 XML 消息,如下所示。

<Message>
    <Header>
        <MsgVerNo>1.0</MsgVerNo>
        <SourceId>XXX</SourceId>
        <MsgRefNo>1234567890</MsgRefNo>
        <LoginId>007</LoginId>
    </Header>
    <Body>
        <![CDATA[<txn>
<id>1234567</id>
<name>XXXX</name>
        </txn>]]>
    </Body>
</Message>

我希望将其转换如下。并应被删除,而子节点应保留。另外,CData 的换行也应该被删除。

<Message>
    <MsgVerNo>1.0</MsgVerNo>
    <SourceId>XXX</SourceId>
    <MsgRefNo>1234567890</MsgRefNo>
    <LoginId>007</LoginId>
    <txn>
        <record>
            <id>1234567</id>
            <name>XXXX</name>
        </record>
    </txn>
</Message>

我尝试使用下面的 XSLT。但输出并不理想。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Header">
        <xsl:copy-of select="node()"/>
    </xsl:template>
    <xsl:template match="Body">
        <xsl:copy-of select="node()"/>
    </xsl:template>
</xsl:stylesheet>

输出

<Message>
<MsgVerNo>1.0</MsgVerNo>
<SourceId>XXX</SourceId>
<MsgRefNo>1234567890</MsgRefNo>
<LoginId>007</LoginId>
    &lt;txn&gt;
&lt;id&gt;1234567&lt;/id&gt;
&lt;name&gt;XXXX&lt;/name&gt;
    &lt;/txn&gt;
</Message>

到目前为止我还没有运气。请专家帮忙。谢谢。

最佳答案

CDATA 元素意味着您的解析不会将其间的数据解释为 XML。这就是 CDATA 的具体目的。您可以发送字符数据,包括 < >,而解析器不会尝试解释它并且可能会失败。

出于所有意图和目的,您的 Body 节点仅包含文本。您可以将其作为文本读取,甚至可以去掉 CDATA 标记,但这仍然会留下看起来像 XML 的文本,而不是被解释为 XML 的内容。

您可以使用以下内容来获取内容,但是如果您想进一步解析 body 元素的内容,则必须将其传递给另一个 XSLT。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Header">
        <xsl:copy-of select="node()"/>
    </xsl:template>
    <xsl:template match="Body">
        <xsl:value-of select="." disable-output-escaping="yes"/>
    </xsl:template>
</xsl:stylesheet>

关于xslt - 关于 XSLT 的问题,以消除子节点位于 CDATA 部分的父节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52927466/

相关文章:

css - 从数据库中检索数据并将它们显示在表格中后,长行会扩展单元格,而不是中断

python - 当不同的子元素名称匹配时如何连接子元素

xslt - 如何添加到元素,如果需要首先创建它

xml - 使用 XSLT 转储文件以获取源 XML

jquery - 如何在生成的 HTML 上强制使用单一字体?

由 Javascript 加载的 XSL 中的 Javascript

c - 由 C libxml 和 libxslt 提供支持的 node.js

html - 如何使用 XSLT 构建字母 Accordion ?

xml - 如何输出xls中的所有xml?

xml - XSLT 从子目录转换多个文件