简体   繁体   中英

XML transformation sort and keep CDATA tags

I have XML files similar to following

<?xml version="1.0" encoding="UTF-8"?>
<domData CHECK_STATE="P">
  <K>
    <![CDATA[F]]>
  </K>
  <P>
    <![CDATA[F]]>
  </P
  <L>
    <![CDATA[F
    CC
    DD
    GEJ]]>
  </L>
  <D/>
  <E/>
  <A>TEST</A>
  <B>
  <![CDATA[<root><iA>DATA</iA><iB>DDDD</iB><</root>]]>
  </B>
</domData>

and I have following transformation

<xsl:stylesheet version="1.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="@*">
                <xsl:sort select="name()"/>
            </xsl:apply-templates>

            <xsl:apply-templates select="node()">
                <xsl:sort select="name()">
                </xsl:sort>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

above transformation removes all CDATA and escapes inner xml entities.

I can't use "cdata-section-elements" as the number elements is huge and I would like to use the same xslt for different XML files as well.

My problem is that I need to keep the CDATA tags and the inner xml as it is. is it possible? Thx

I can't use "cdata-section-elements" as the number elements is huge and I would like to use the same xslt for different XML files as well.

cdata-section-elements is the only standard way to make an XSLT output CDATA sections. It certainly isn't possible to preserve CDATA sections exactly as they were in the input document as the information about which text nodes were originally CDATA sections and which were plain text nodes simply isn't available in the XPath data model. But it shouldn't be necessary as CDATA sections are only a syntactic sugar, and they are exactly equivalent to the entity-escaped form as far as any XML processor is concerned.

There may be a processor-specific trick you could use but that depends on which XSLT processor you will be using. Failing that you may wish to consider a non-XSLT solution, using an object model such as DOM which can be configured to preserve the original CDATA structure.

If CDATA tags convey information, start by replacing them with something else that XSLT understands and retains in the data model. You can do this with a SAX filter pass on the input side of your XSLT processing, and you can convert elements back to CDATA tags in a similar filter pass on the output side.

However, anyone who uses CDATA section boundaries to carry information should be shot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM