简体   繁体   中英

escaped xml with cdata that has also has both escaped data value and tags

I am receiving xml data from a web service that returns all the data as one escaped xml string. however for whatever reason, part of the xml is enclosed within a cdata tag. The escape xml within the cdata will often contain escaped xml character as well. example:

<root>
  <importData>dat</importData>
  <Response>
   <![CDATA[&lt;SecondRoot&gt;
   &lt;Data&gt;123&lt;/Data&gt;
   &lt;DataEscapedCharacterIncluded&gt; 3 &gt; 1&lt;/DataEscapedCharacterIncluded&gt;
   &lt;/SecondRoot&gt;]]>
  &lt;/Response&gt;
&lt;/root&gt;

I need to transform both the xml inside and out of the cdata section into another xml format with xsl, but I'm having a hard time figuring out how to get this into a usable xml form with either c# or xsl so I can do the xsl transform into a different format. I would like it look like below:

  <root>
     <importData>dat</importData>
     <Response>
      <SecondRoot>
       <Data>123</Data>
       <DataEscapedCharacterIncluded> 3 &gt; 1</DataEscapedCharacterIncluded>
      </SecondRoot>
     </Response>
  <root>

The data you show may not be properly escaped. If you unescape it, it may yield not well-formed XML. Consider this line:

&lt;DataEscapedCharacterIncluded&gt; 3 &gt; 1&lt;/DataEscapedCharacterIncluded&gt;

If you unescape it, it will become this:

<DataEscapedCharacterIncluded> 3 > 1</DataEscapedCharacterIncluded>

This is still valid (a greater-than does not need to be escaped), but I assume that you'll also have &lt; in there somewhere, which must be escaped. If it is doubly escaped you should be fine.

To transform this there are several things you can do:

  • With XSLT 1.0 or 2.0, transform it in two passes, one that does the unescaping with disable-output-escaping set to yes , and another one to do the actual transformation.
  • Use an extension function that takes a string and returns a node set.
  • With XSLT 3.0, use the new function fn:parse-xml or fn:parse-xml-fragment , which can take XML-as-a-string as input.
  • If your entire source is escaped, as it looks like, feed it unescaped to the XSLT processor as explained here . This will also take care of the escaped CDATA (but that part will remain escaped, see below).

What is not entirely clear from your post is whether it is doubly escaped. Ie, if your data looks like this:

<elem><![CDATA[<root>bla</root>]]></elem>

it is singly escaped. If it looks like this:

<elem><![CDATA[&lt;root&gt;bla&lt;/root&gt;]]></elem>

it is doubly escaped. In the latter case, you will need to do an extra unescape cycle before you can process it.

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