序列化为xml和名称空间位置

本文关键字:空间 位置 xml 序列化 | 更新日期: 2023-09-27 18:14:43

我有一个带有按钮的网页。单击后,我将变量传递给一个类以创建xml文件。我正试图在名为Message的元素下添加我的名称空间。

这是我的班级:

using System.Xml.Serialization;
// 
// This source code was auto-generated by xsd, Version=4.0.30319.1.
// 

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]

public partial class Request
    {
    private string sNameField;

    /// <remarks/>
    public string SName
    {
        get
        {
            return this.sNameField;
        }
        set
        {
            this.sNameField = value;
        }
    }

    /// <remarks/>
    public Message Message
    {
        get
        {
            return this.messageField;
        }
        set
        {
            this.messageField = value;
        }
    }
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
public partial class Message
{
    private AddO addOField;
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://pd.com")]
    public AddO AddO
    {
        get
        {
            return this.addOField;
        }
        set
        {
            this.addOField = value;
        }
    }
}
/// <remarks/>
   [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://pd.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://pd.com", IsNullable = false)]
public partial class AddO
{
    private CaseD caseD;
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.a.com")]
    public CaseD CaseD
    {
        get
        {
            return this.caseDField;
        }
        set
        {
            this.caseDField = value;
        }
    }
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.a.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.a.com", IsNullable = false)]
public partial class CaseD
{
    private CaseA caseAField;
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.z.com")]
    public CaseA CaseA
    {
        get
        {
            return this.caseAField;
        }
        set
        {
            this.caseAField = value;
        }
    }
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.z.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.z.com", IsNullable = false)]
public partial class CaseA
{
    private Doc docField;
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.a.com")]
    public DocuE DocE
    {
        get
        {
            return this.docEField;
        }
        set
        {
            this.docEField = value;
        }
    }
}

这是我的按钮事件:

caseA caseA = new caseA();

            caseD caseD = new caseD();
            caseD.caseA = caseA;

            addO addO = new addO();
            addO.caseD = caseD;

            Message Message = new Message();
            Message.addO = addO;
            Request  Request = new  Request();
            Request.Message = Message;
            Request.SName = "Hi";

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("z", "http://www.z.com");
            ns.Add("pd", "http://pd.com");
            ns.Add("a", "http://www.a.com");
    XmlSerializer serializer = new XmlSerializer(typeof(Request), new Type[] {typeof(Message), typeof(addO), typeof(caseD), typeof(caseA)});
            StreamWriter writer = new StreamWriter(Server.MapPath("~/images/test.xml"));
            serializer.Serialize(writer, Request, ns);

我在XML中得到这个:

<?xml version="1.0" encoding="utf-8"?>
<Request xmlns:a="http://www.a.com">
  <SName>hi</SName>
  <Message>
    <addO xmlns="http://pd.com">
      <a:caseD>
        <caseA xmlns="http://www.z.com">
        </caseA>
      </a:caseD>
    </addO>
  </Message>
</Request>

我需要名称空间只在Message元素下面:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Request>
<SName>Hi</SName>
    <Message>
        <pd:addO
xmlns:a="http://www.a.com" 
xmlns:z="http://www.z.com" 
xmlns:pd="http://pd.com">
            <a:caseD>
                <z:caseA>
                </z:caseA>
            </a:caseD>
        </pd:addO>
    </Message>
</Request>

序列化为xml和名称空间位置

根元素或子元素是否具有名称空间定义并不重要——您的两个XML示例在语义上是相同的。

然而,如果您正在处理的接收系统不能正确处理此问题,则可以利用[XmlAnyElementAttribute]属性对XmlSerializer进行嵌套序列化,将AddO元素的内部序列化的结果(包括所需的名称空间)嵌入Request的外部序列化中。

首先,您需要一些扩展方法来序列化XElement类和其他相关实用程序:

public static class XmlExtensions
{
    public static XmlSerializerNamespaces NoStandardXmlNamespaces()
    {
        var ns = new XmlSerializerNamespaces();
        ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
        return ns;
    }
    public static T Deserialize<T>(this XContainer element, XmlSerializer serializer = null)
    {
        using (var reader = element.CreateReader())
        {
            object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader);
            if (result is T)
                return (T)result;
        }
        return default(T);
    }
    public static XElement SerializeToXElement<T>(this T obj)
    {
        return obj.SerializeToXElement(null, NoStandardXmlNamespaces());
    }
    public static XElement SerializeToXElement<T>(this T obj, XmlSerializerNamespaces ns)
    {
        return obj.SerializeToXElement(null, ns);
    }
    public static XElement SerializeToXElement<T>(this T obj, XmlSerializer serializer, XmlSerializerNamespaces ns)
    {
        var doc = new XDocument();
        using (var writer = doc.CreateWriter())
            (serializer ?? new XmlSerializer(obj.GetType())).Serialize(writer, obj, ns);
        var element = doc.Root;
        if (element != null)
            element.Remove();
        return element;
    }
    public static T LoadFromXML<T>(this string xmlString, XmlSerializer serializer = null)
    {
        serializer = serializer ?? new XmlSerializer(typeof(T));
        T returnValue = default(T);
        using (StringReader reader = new StringReader(xmlString))
        {
            object result = serializer.Deserialize(reader);
            if (result is T)
            {
                returnValue = (T)result;
            }
        }
        return returnValue;
    }
    public static string GetXml<T>(this T obj, XmlSerializerNamespaces ns, bool? standalone)
    {
        return GetXml(obj, null, ns, standalone);
    }
    public static string GetXml<T>(T obj, XmlSerializer serializer, XmlSerializerNamespaces ns, bool? standalone)
    {
        serializer = serializer ?? new XmlSerializer(obj.GetType());
        using (var textWriter = new Utf8StringWriter())
        {
            var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " }; // For cosmetic purposes.
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
            {
                if (standalone != null)
                    xmlWriter.WriteStartDocument(standalone.Value);
                serializer.Serialize(xmlWriter, obj, ns);
            }
            return textWriter.ToString();
        }
    }
    public static string RootXmlElementName(this Type type)
    {
        var xmlRoot = type.GetCustomAttribute<XmlRootAttribute>();
        if (xmlRoot != null && !string.IsNullOrEmpty(xmlRoot.ElementName))
            return xmlRoot.ElementName;
        return type.Name;
    }
}
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding
    {
        get { return Encoding.UTF8; }
    }
}
接下来,定义包括Message类在内的类,如下所示。请注意,你的问题中的类不编译(一些缺失的类型),所以我简化了它们:
public class Request
{
    public string SName { get; set; }
    public Message Message { get; set; }
}
public static class Namespaces
{
    public const string pd = "http://pd.com";
    public const string a = "http://www.a.com";
    public const string z = "http://www.z.com";
    public static XmlSerializerNamespaces GetNamespaces()
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("pd", pd);
        ns.Add("a", a);
        ns.Add("z", z);
        return ns;
    }
}
public class Message
{
    [XmlIgnore]
    public AddO AddO { get; set; }
    // Do nested serialization here
    [XmlAnyElement]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public XElement[] AddOXml
    {
        get
        {
            if (AddO == null)
                return null;
            var ns = Namespaces.GetNamespaces();
            var element = AddO.SerializeToXElement(ns);
            element.Name = element.Name.Namespace + "addO";
            return new[] { element };
        }
        set
        {
            if (value == null || value.Length == 0)
                AddO = null;
            AddO = value.Select(x => { x.Name = x.Name.Namespace + typeof(AddO).RootXmlElementName(); return x.Deserialize<AddO>(); }).FirstOrDefault();
        }
    }
}
[XmlRoot(Namespace = Namespaces.pd)]
public class AddO
{
    [XmlElement("caseD", Namespace = Namespaces.a )]
    public CaseD CaseD { get; set; }
}
public class CaseD
{
    [XmlElement("caseA", Namespace = Namespaces.z)]
    public CaseA CaseA { get; set; }
}
public class CaseA
{
    public string Value { get; set; }
}

现在,测试:

public class TestClass
{
    public static void Test()
    {
        var request = new Request
        {
            SName = "Hi",
            Message = new Message
            {
                AddO = new AddO
                {
                    CaseD = new CaseD { CaseA = new CaseA { Value = "Test Value" } },
                }
            }
        };
        var xml = request.GetXml(XmlExtensions.NoStandardXmlNamespaces(), true);
        Debug.WriteLine(xml);
        var request2 = xml.LoadFromXML<Request>();
        Debug.WriteLine(request2.GetXml(XmlExtensions.NoStandardXmlNamespaces(), true));
        Debug.Assert(request.Message.AddO.CaseD.CaseA.Value == request2.Message.AddO.CaseD.CaseA.Value); // No assert.
    }
}

原型小提琴。XML输出为:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Request>
    <SName>Hi</SName>
    <Message>
        <pd:addO xmlns:z="http://www.z.com" xmlns:a="http://www.a.com" xmlns:pd="http://pd.com">
            <a:caseD>
                <z:caseA>
                    <z:Value>Test Value</z:Value>
                </z:caseA>
            </a:caseD>
        </pd:addO>
    </Message>
</Request>