簡體   English   中英

彼此內部的XML序列化元素

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM