简体   繁体   中英

Embedding an xml document inside an xml string

I have a web service that returns an xml string as results. The return string is in this format:

<ReturnValue>
   <ErrorNumber>0
</ErrorNumber>
<Message>my message</Message>
</ReturnValue>

The data that I want to insert into the "message" tag is a serialized version of a custom object. The serialized format of that object contains xml and namespace declarations post serialization. When that gets thrown into the "message" tag of my return xml string, XmlSpy says that it's not well-formed. How should I get rid of the namespace declarations, or is there a different way to imbed a serialized object into an xml string?

Just make sure that your <Message> XML is encoded so that < , > , " , and & show up as &lt; , &gt; , &quot; and &amp; , respectively.

There are few built-in ways to encode the characters:

string message = System.Web.HttpUtility.HtmlEncode(serializedXml);

string message = System.Security.SecurityElement.Escape(serializedXml);
  • Using an XmlTextWriter to do the work for you
  • Use CDATA to wrap your XML

Also, this is probably a duplicate of:

  1. Best way to encode text data for XML

Wrap the string in CDATA like so:

<![CDATA[your xml, which can be multi-line]]>

CDATA will inform a validator to treat the CDATA contents as ignored text. It's often the most expedient way to embed XML (or taggy non-XML content) as a string. You can run into problems if your embedded XML contains its own CDATA, but otherwise it's a simple fix.

Think of XML as a document not a string. Create a node named "wrapper", and store the content of your file in it as a Base64 encoded string. The results will look like this.

<ReturnValue>
  <ErrorNumber>0</ErrorNumber>
  <Message>my message</Message>
  <wrapper type="bin.base64">PD94bWwgdmVyc2lvbj0iMS4wIj8+PHhzbDpzdHlsZXNoZWV0IHZ
lcnNpb249IjEuMCIgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0
iIHhtbG5zOm1zeHNsPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnhzbHQiPjx4c2w6b3V0cHV0IG1
ldGhvZD0ieG1sIiAvPjx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPjwveHNsOnRlbXBsYXRlPjwveHNsOnN
0eWxlc2hlZXQ+</wrapper>
</ReturnValue>

The following code shows how to add the wrapper, encode the content. Then it reverses the process to show that it all "works".

Using Base64 in XML has a number of other applications as well. For example embedding images, or other documents in XML content.

using System;
using System.IO;
using System.Xml;

public class t
{

    static public string EncodeTo64(string toEncode) {
        byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
        return returnValue;
    }

    static public string DecodeFrom64(string encodedData) {
        byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
        string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
        return returnValue;
    }

    public static void Main() {
        try {
        //Create the XmlDocument.
        XmlDocument doc = new XmlDocument();
            doc.LoadXml( @"
            <ReturnValue>
            <ErrorNumber>0</ErrorNumber>
            <Message>my message</Message>
            </ReturnValue>
            ");

            XmlNode nodeMessage = doc.SelectSingleNode( "/ReturnValue/Message" );
            if( nodeMessage != null ) {
            XmlDocument docImport = new XmlDocument();
                docImport.Load( "docwithnamespace.xml" );

                // create a wrapper element for the file, then import and append it after <Message>
                XmlElement nodeWrapper = (XmlElement)doc.CreateElement( "wrapper" );
                nodeWrapper.SetAttribute( "type", "bin.base64" );

                nodeWrapper = (XmlElement)doc.ImportNode( nodeWrapper, true );
                XmlNode ndImport = nodeMessage.ParentNode.AppendChild( nodeWrapper.CloneNode( true ) );
                ndImport.InnerText = EncodeTo64( docImport.OuterXml );
                doc.Save( "wrapperadded.xml" );

                // Next, let's test un-doing the wrapping
                // Re-load the "wrapped" document
                XmlDocument docSaved = new XmlDocument();
                docSaved.Load( "wrapperadded.xml" );

                // Get the wrapped element, decode from base64 write to disk
                XmlNode node = doc.SelectSingleNode( "/ReturnValue/wrapper" );
                if( node != null ) {
                    // Load the content, and save as a new XML
                    XmlDocument docUnwrapped = new XmlDocument();
                    docUnwrapped.LoadXml( DecodeFrom64( node.InnerText ) );
                    docUnwrapped.Save( "unwrapped.xml" );
                    Console.WriteLine( "Eureka" );
                }
            }


        } catch( Exception e ) {
            Console.WriteLine(e.Message);
        }
    }
}

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