Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting xml/CDATA into a xml file?

Tags:

xml

cdata

I need to put a rather large xml file into another xml file. I considered using CDATA for this:

http://www.w3.org/TR/2000/REC-xml-20001006#sec-cdata-sect http://www.w3schools.com/xml/xml_cdata.asp

but since my xml might also contain CDATA this does not work unless I do some nasty workaround:

http://web-design.blogs.webucator.com/2010/11/20/nesting-cdata-blocks/

Are there better ways of transferring/encoding large nested xml files or is the xml format simply not meant to be used in this way?

like image 249
u123 Avatar asked Jun 22 '26 10:06

u123


2 Answers

you can replace the inner ]] with ]]]]><![CDATA[

(based on http://web-design.blogs.webucator.com/2010/11/20/nesting-cdata-blocks/ )

Example: We have outer and inner docs and we want to put the inner inside the outer as CDATA.

<outer>
  <e1 name="abc"/>
  <innerDoc><![CDATA[
      <Doc1/>
    ]]></innerDoc>
</outer>

<inner>
  <innrer1/>
  <a><![CDATA[
      free text with << >
    ]]></a>
  <innrer2/>
</inner>

if we just copy and paste we get an invalid xml

<outer>
  <e1 name="abc"/>
  <innerDoc><![CDATA[
      <inner>
        <innrer1/>
        <a><![CDATA[
            free text with << >
          ]]></a>
        <innrer2/>
      </inner>
    ]]></innerDoc>
</outer>

however, if we replace the inner ]] with ]]]]><![CDATA[ before embedding it we fix the problem

<outer>
  <e1 name="abc"/>
  <innerDoc><![CDATA[
      <inner>
        <innrer1/>
        <a><![CDATA[
            free text with << >
          ]]]]><![CDATA[></a>
        <innrer2/>
      </inner>
    ]]></innerDoc>
</outer>
like image 190
Shai Ben-Yehuda Avatar answered Jun 25 '26 01:06

Shai Ben-Yehuda


Yes, in your top-most document make the CDATA section of data type bin.base64. That way even if the document you're wrapping contains a CDATA section, you're protected. As an added bonus, your application will also support binary files (images, spreadsheets, etc.).

Here's some code that does it, based on Microsoft ADO, and MSXML.

function wrapBinaryFile( strFileName)
{
    var ado_stream = new ActiveXObject("ADODB.Stream");
    var xml = newXMLDocument();
    xml.loadXML("<file/>");
    xml.documentElement.setAttribute( "name", strFileName );

    xml.documentElement.setAttribute("xmlns:dt","urn:schemas-microsoft-com:datatypes");

    xml.documentElement.dataType = "bin.base64";
    ado_stream.Type = 1; // 1=adTypeBinary
    ado_stream.Open();
    ado_stream.LoadFromFile( strFileName );
    xml.documentElement.nodeTypedValue = ado_stream.Read(-1); // -1=adReadAll
    ado_stream.Close();
    return xml;
}

And how to un-wrap it on the other end...

function unwrapBinaryFile(ndFile, strFileName )
{
    var ado_stream = new ActiveXObject("ADODB.Stream");
    ndFile.dataType = "bin.base64";

    ado_stream.Type = 1; // 1=adTypeBinary
    ado_stream.Open();
    ado_stream.write( ndFile.nodeTypedValue );
    ado_stream.SaveToFile( strFileName, 2 );
    ado_stream.Close(); 
}
like image 38
William Walseth Avatar answered Jun 25 '26 02:06

William Walseth