[英]XML Serialize elements inside one another
我有一個可以自己序列化的類,例如:
[XmlRoot("NameOfMyRoot", Namespace = "myNamespace")]
public class Inner
{
public Inner(){}
public string SomeString { get; set; }
}
完美地序列化為(我正在使用ns
別名作為myNamespace
,請參閱完整的演示)
<?xml version="1.0" encoding="utf-16"?>
<NameOfMyRoot xmlns:ns="myNamespace">
<ns:SomeString></ns:SomeString>
</NameOfMyRoot>
現在,我希望該對象成為另一個對象(包裝器)的一部分:
[XmlRoot("Root")]
public class Outer<T>
{
public T Property{ get; set; }
public Outer(){}
public Outer(T inner)
{
Property = inner;
}
}
這給了我這個:
<?xml version="1.0" encoding="utf-16"?>
<Root xmlns:ns="myNamespace">
<Property>
<ns:SomeString></ns:SomeString>
</Property>
</Root>
我想要的只是將內部對象原樣嵌入其父對象,如下所示:
<?xml version="1.0" encoding="utf-16"?>
<Root>
<NameOfMyRoot xmlns:ns="myNamespace">
<ns:SomeString></ns:SomeString>
</NameOfMyRoot>
</Root>
請注意,名稱空間不應移至根目錄,我也不能指定元素的名稱,因為會有許多不同的類型。 擺弄完整的例子 。
當然,我可以將它們分別序列化並通過一些討厭的字符串操作進行組合,但是我希望有一種巧妙的方法可以實現此目的。
沒有簡單的方法可以做到這一點。 不過,您可以在運行時執行此操作:
// perhaps discover these details at runtime
var attribs = new XmlAttributeOverrides();
attribs.Add(typeof(Outer<Inner>), "Property", new XmlAttributes
{
XmlElements = { new XmlElementAttribute {ElementName = "NameOfMyRoot" } }
});
attribs.Add(typeof(Inner), "SomeString", new XmlAttributes
{
XmlElements = { new XmlElementAttribute { Namespace = "myNamespace"} }
});
var ser = new XmlSerializer(typeof(Outer<Inner>), attribs);
var obj = new Outer<Inner> { Property = new Inner { SomeString = "abc" } };
ser.Serialize(Console.Out, obj);
請注意,您必須存儲並重新使用這樣的序列化程序; 對於簡單的new XmlSerializer()
示例,序列化器在內部進行緩存並重新使用。 但是,對於像這樣的非常規情況, 每次都會發出一個新的動態類型,因此您將泄漏內存(不會被卸載)。
那給你:
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<NameOfMyRoot>
<SomeString xmlns="myNamespace">abc</SomeString>
</NameOfMyRoot>
</Root>
如果您不希望使用這兩個xmlns
別名聲明,則可以分別刪除它們,但是它們至少對於兼容的閱讀器而言不會改變含義。 同樣,可以將ns
添加為別名:
var obj = new Outer<Inner> { Property = new Inner { SomeString = "abc" } };
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
ns.Add("ns", "myNamespace");
ser.Serialize(Console.Out, obj, ns);
這使:
<Root xmlns:ns="myNamespace">
<NameOfMyRoot>
<ns:SomeString>abc</ns:SomeString>
</NameOfMyRoot>
</Root>
作為替代方法:
using System;
using System.Xml;
using System.Xml.Serialization;
[XmlRoot("NameOfMyRoot")]
public class Inner
{
public Inner() { }
[XmlElement(Namespace = "myNamespace")]
public string SomeString { get; set; }
}
static class Program
{
static void Main()
{
using (XmlWriter writer = XmlWriter.Create(Console.Out))
{
writer.WriteStartDocument(false);
writer.WriteStartElement("Root");
var ser = new XmlSerializer(typeof(Inner));
var obj = new Inner { SomeString = "abc" };
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
ns.Add("ns", "myNamespace");
ser.Serialize(writer, obj, ns);
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
}
我在這里所做的是手動編寫根節點,並且僅讓XmlSerializer
編寫內部內容。 請注意,我必須更改SomeString
周圍的屬性以使其按您期望的方式工作(其中是具有名稱空間的字符串,而不是對象)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.