【问题标题】:Insert or update XMLRoot Element dynamically动态插入或更新 XMLRoot 元素
【发布时间】:2017-11-10 21:36:52
【问题描述】:

我在数组上有一个 XMLRoot 和一个 XMLElement 的类。基于客户端,当我序列化我的类时,我必须更改 XMLRoot 和 XMLElement。有没有办法动态改变它

[XmlRoot("sample")]
public class MyData
{
    private ArrayList map;

    public MyData()
    {
        map = new ArrayList();
    }

    [XmlElement("url")]
    public Location[] Locations
    {
        get
        {
            Location[] items = new Location[map.Count];
            map.CopyTo(items);
            return items;
        }

        set
        {
            if (value == null)
                return;
            Location[] items = (Location[])value;
            map.Clear();
            foreach (Location item in items)
                map.Add(item);
        }
    }

    public int Add(Location item)
    {
        return map.Add(item);
    }
}

如您所见,我的根是“sample”,根据客户端,它可以是“sample”或“reserved”。 XMLElement 是“url”,根据客户端可以是“url”或“dataitem”

我正在使用 XMLSerializer 进行序列化

// My condition needs to be here to determine which 
// root and xmlelement should use
var xs = new XmlSerializer(typeof(MyData));
var oString = new StringWriterWithEncoding(Encoding.UTF8);

提前致谢

【问题讨论】:

    标签: c# xml xmlserializer


    【解决方案1】:

    MSDN-Overrides on XmlSerializer

    您可以通过构造函数提供 Overrides - 最好阅读 doku。

    示例:

    using System.Collections;
    using System.Linq;
    using System.Xml;
    using System.Xml.Serialization;
    
    public class Location
    {
        public string L;
    }
    
    [XmlRoot("sample")]
    public class MyData
    {
        public MyData()
        {
            map = new ArrayList();
        }
    
        [XmlElement("url")]
        public Location[] Locations
        {
            get
            {
                Location[] items = new Location[map.Count];
                map.CopyTo(items);
                return items;
            }
    
            set
            {
                if (value == null)
                    return;
                Location[] items = (Location[])value;
                map.Clear();
                foreach (Location item in items)
                    map.Add(item);
            }
        }
    
        public int Add(Location item)
        {
            return map.Add(item);
        }
    
        private ArrayList map;
    }
    
    internal class Program
    {
    

    Xml 打印到屏幕:

        private static void DoSerialize(MyData m, XmlSerializer xs)
        {
            var settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.NewLineOnAttributes = true;
    
            var sww = new System.IO.StringWriter();
            XmlWriter writer = XmlWriter.Create(sww, settings);
            xs.Serialize(writer, m);
            Console.WriteLine(sww.ToString().Replace("><", ">\r\n<"));
        }
    

    重载构造函数的使用:

        static void Main()
        {
            // testdata
            MyData m = new MyData 
            { 
                Locations = new Location[2] 
                { 
                    new Location { L = "L1" }, 
                    new Location { L = "L2" } 
                } 
            };
    
            // simple Serializer
            var xs = new XmlSerializer(typeof(MyData));
    
            DoSerialize(m, xs);
            Console.WriteLine();
    
    
            var xs2 = new XmlSerializer(typeof(MyData), XmlAttributeOverride(),
                         new Type[] { typeof(Location[]) }, RootOverride(), "");
    
            DoSerialize(m, xs2);
    
            Console.ReadLine();
        }
    
        // override the root node
        private static XmlRootAttribute RootOverride() => new XmlRootAttribute("OtherName");
    
        // override your Languages property
        private static XmlAttributeOverrides XmlAttributeOverride()
        {
            var attrs = new XmlAttributes();
            attrs.XmlElements.Add(new XmlElementAttribute("Location"));
    
            var o = new XmlAttributeOverrides();
            o.Add(typeof(MyData), "Locations", attrs);
            return o;
        }
    }
    

    输出:

    <sample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
    www.w3.org/2001/XMLSchema">
      <url>
        <L>L1</L>
      </url>
      <url>
        <L>L2</L>
      </url>
    </sample>
    
    <OtherName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http
    ://www.w3.org/2001/XMLSchema">
      <Location>
        <L>L1</L>
      </Location>
      <Location>
        <L>L2</L>
      </Location>
    </OtherName>
    

    【讨论】:

    • 它几乎按照您的解决方案工作。我现在唯一遇到的问题是我在 级别获得了我不想要的 xmlns 声明
    • 创建一个新的 SO 问题并提供详细信息。我很高兴得到赞成或接受的答案。
    • 我得到 w3.org/2001/XMLSchema-instance" xmlns:xsd="w3.org/2001/XMLSchema"> sitemaps.org/schemas/sitemap/0.9"> domaincom/url.html</loc> always2017-09-11T04:50:27Z
    • 在新问题中发布您的新代码。发布数据。发布期望的结果。评论对这个不好。我的猜测是你必须摆弄 XmlWriterSettings 的选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多