在xml字符串中嵌入xml文档

本文关键字:xml 文档 字符串 | 更新日期: 2023-09-27 18:16:02

我有一个web服务,返回一个xml字符串作为结果。返回字符串的格式是:

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

我想插入到"message"标签中的数据是自定义对象的序列化版本。该对象的序列化格式包含序列化后的xml和名称空间声明。当它被扔到我返回的xml字符串的"message"标记中时,XmlSpy说它不是格式良好的。我应该如何摆脱名称空间声明,或者是否有其他方法将序列化的对象嵌入到xml字符串中?

在xml字符串中嵌入xml文档

像这样在CDATA中包装字符串:

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

CDATA将通知验证器将CDATA内容视为忽略的文本。这通常是将XML(或标记非XML内容)作为字符串嵌入的最方便的方法。如果您嵌入的XML包含自己的CDATA,则可能会遇到问题,但除此之外,这是一个简单的修复。

只要确保您的<Message> XML被编码,以便<, >, "&分别显示为&lt;, &gt;, &quot;&amp;

有几个内置的方法来编码字符:

string message = System.Web.HttpUtility.HtmlEncode(serializedXml);
string message = System.Security.SecurityElement.Escape(serializedXml);
  • 使用XmlTextWriter为您完成工作
  • 使用CDATA来包装XML

也可能是:

的重复
    为XML编码文本数据的最佳方式

将XML视为文档而不是字符串。创建一个名为"wrapper"的节点,并将文件的内容存储为Base64编码的字符串。结果如下所示:

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

下面的代码展示了如何添加包装器,对内容进行编码。然后,它会反转这个过程,以显示它全部"工作"。

在XML中使用Base64还有许多其他应用。例如在XML内容中嵌入图像或其他文档。

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);
        }
    }
}