【问题标题】:Embedding an xml document inside an xml string [duplicate]在 xml 字符串中嵌入 xml 文档 [重复]
【发布时间】:2011-11-29 19:59:54
【问题描述】:

我有一个 Web 服务,它返回一个 xml 字符串作为结果。返回字符串的格式如下:

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

我要插入“消息”标签的数据是自定义对象的序列化版本。该对象的序列化格式包含序列化后的 xml 和命名空间声明。当它被扔到我的返回 xml 字符串的“消息”标签中时,XmlSpy 说它的格式不正确。我应该如何摆脱命名空间声明,或者是否有其他方法可以将序列化对象嵌入到 xml 字符串中?

【问题讨论】:

  • 嵌入数据中的冗余或新命名空间声明不应导致格式正确错误,但在 &lt;Message&gt; 元素中嵌入 XML 声明可能会导致该错误。如果删除额外的 XML 声明不能解决问题,那么您的对象序列化或 Web 服务返回值会产生格式错误的 XML。

标签: c# xml


【解决方案1】:

将字符串包装在 CDATA 中,如下所示:

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

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

【讨论】:

    【解决方案2】:

    只需确保您的 &lt;Message&gt; XML 已编码,以便 &amp;lt;&amp;gt;"&amp;amp; 显示为 &amp;lt;&amp;gt;&amp;quot;&amp;amp; ,分别。

    编码字符的内置方法很少:

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

    另外,这可能是以下内容的副本:

    1. Best way to encode text data for XML

    【讨论】:

    • 这会像对那些特殊 xml 字符的所有不同表示形式做一个 string.replace 一样简单吗?
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-24
      • 2011-02-03
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多