关于XSLT的问题,以消除CDATA部分中子代所在的父节点

时间:2018-10-22 10:44:42

标签: 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>

到目前为止我还没有运气。请专家提供任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

CDATA元素意味着之间的数据不会被您的解析解释为XML。这是CDATA的特定目的。您可以发送字符数据,包括<>,而无需解析器尝试解释它并可能导致失败。

出于所有意图和目的,“正文”节点仅包含文本。您可以将其读取为文本,甚至可以剥离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>