序列化为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示例在语义上是相同的。
然而,如果您正在处理的接收系统不能正确处理此问题,则可以利用[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>