【问题标题】:c#: deserialize unknown xml elements to an array or listc#:将未知的xml元素反序列化为数组或列表
【发布时间】:2015-04-13 04:01:14
【问题描述】:

给定以下 XML:

<browser>
    <firefox company="mozilla"></firefox>
    <chrome company="google"></chrome>
    <ie company="microsoft"></ie>     
</browser>

这是我的反序列化代码:

[XmlRoot("browser")]
public class Browser
{
    //--List or Array
    List<BrowserType> browserTypes {get; set;}
}

public class BrowserType
{
    [XmlAttribute("company")]
    public string company {get; set;}
}

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Browser));
StreamReader sr = new StreamReader("browser.xml");
Browser browser = (Browser )xmlSerializer.Deserialize(sr);

foreach(var item in browserTypes)
{
    //--List browser types 
}

对于这个问题,我无法为 XmlArrayItem 执行以下代码,因为我不知道元素名称。

[XmlArray("browser")]
[XmlArrayItem("firefox")]
public BrowserType[] BrowserTypes{ get; set; }

如何将未知的xml元素反序列化为数组或列表?

【问题讨论】:

    标签: c# xml xml-parsing xml-deserialization


    【解决方案1】:

    更新

    好的,所以使用 xml 序列化,您可以指定 BrowserTypes 的列表,然后为每个派生类型指定 XmlElement 名称和类型。示例:

    [XmlRoot("browser")]
    public class Browser
    {
        private readonly List<BrowserType> _items = new List<BrowserType>();
        [XmlElement("firefox", typeof(Firefox))]
        [XmlElement("chrome", typeof(Chrome))]
        [XmlElement("ie", typeof(IE))]
        public List<BrowserType> Items { get { return _items; } }
    }
    
    public class BrowserType
    {
        [XmlAttribute("company")]
        public string Company { get; set; }
    }
    
    public class Firefox : BrowserType
    {
    }
    
    public class Chrome : BrowserType
    {
    }
    
    
    public class IE : BrowserType
    {
    }
    

    原始条目:

    如果你可以切换到XDocument,那么你可以获取根节点的所有后代,然后获取每个后代的名称。示例:

        static void Main(string[] args)
        {
            string xmlString = @"<browser>
    <firefox company=""mozilla""></firefox>
    <chrome company=""google""></chrome>
    <ie company=""microsoft""></ie>     
    </browser>";
    
            XDocument xdoc = XDocument.Parse(xmlString);
            var elementNames = xdoc.Root.Descendants()      // Get the descendants of the root node
                                        .Select(element => element.Name.LocalName);     // Project each XElement to its name
            string[] browserTypes = elementNames.ToArray();
    
            foreach (string browserType in browserTypes)
            {
                Console.WriteLine(browserType);
            }
        }
    

    输出:

    firefox
    chrome
    ie
    

    【讨论】:

    • 是的,我可以使用 linq to xml 获取这些元素。但我在这里要做的是基于 xml 模式构造类。我期待有类似 [XmlArray("browser")] [XmlArrayItem("firefox")] public BrowserType[] BrowserTypes{ get;放; }
    • 感谢更新的答案。我绝对可以做到。但只是为了澄清,在我运行反序列化时,程序不知道这些元素。我的意思是 firefox、chrome 和 ie 都是未知元素,所以我不能为它们创建类并在 XElement 的 typeof() 中定义它们。有什么办法可以动态设置 XElement 属性。好吧,我能够使用 new XmlRootAttribute("whatever root name u want") 对 XmlRoot 元素执行此操作,但不确定如何为子元素执行此操作。
    • 哦,我明白了。我不知道该怎么做。 :) 根据这个accepted answer,您可以使用 XmlDocument 或 XDocument(就像我原来的答案一样),或者他还建议使用 Json.NET(我猜它支持 XML)。祝你好运!
    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多