我有一个带按钮的网页。点击后,我将我的变量传递给一个类来创建一个xml文件。我试图在名为Message的元素下添加我的命名空间。它无法正常工作。
这是我的班级:
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 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>
我用XML得到这个:
<?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>
我需要名称空间只在Message元素下:
openrowset
答案 0 :(得分:0)
根元素或子元素是否具有命名空间定义无关紧要 - 您的两个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.
}
}
原型fiddle。 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>