【问题标题】:How to parse XML with several Attributes and an options list如何使用多个属性和选项列表解析 XML
【发布时间】:2020-05-30 05:39:06
【问题描述】:

我有一个类似下面的 XML 文件:

<root>
    <data label="product data" min="0" max="10">
        <option>
            <id>1</id>
            <name>Name1</name>
        </option>
        <option>
            <id>2</id>
            <name>Name2</name>
        </option>
        <option>
            <id>3</id>
            <name>Name3</name>
        </option>
    </data>
</root>

我需要同时检索data 属性和选项列表。

我试过了:

[XmlRoot(ElementName = "root")]
public class Data
{
    // Retreive data attributes
    [XmlElement(ElementName = "data")]
    public Options Attributes { get; set; }

    // Retrieve option list
    [XmlArray("data")]
    [XmlArrayItem("option", Type = typeof(GeneralOptions))]
    public GeneralOptions[] Options { get; set; }
}

可选课程:

选项

public class Options
{
    [XmlAttribute("label")]
    public string Label{ get; set; }

    [XmlAttribute("min")]
    public string Min{ get; set; }

    [XmlAttribute("max")]
    public string Max{ get; set; }
}

常规选项

public class GeneralOptions
{
    [XmlElement(ElementName = "id")]
    public string Id { get; set; }

    [XmlElement(ElementName = "name")]
    public string Name{ get; set; }
}

但是当我尝试反序列化对象时,它会启动以下异常:

命名空间“”中的 XML 元素“数据”已存在于当前范围内。使用 XML 属性为元素指定另一个 XML 名称或命名空间。

我想问题是我试图“两次”检索相同的元素。但我需要检索这两件事。我不能使用[Attribute] 的东西,因为有几个属性要检索,我需要使用几个具有相同格式的 XML 元素来执行此操作,并且我想重用它。

那么,我怎样才能同时检索它们呢?

【问题讨论】:

    标签: c# xml xml-parsing xmlserializer xml-attribute


    【解决方案1】:

    你需要稍微重构一下:

    [XmlRoot("root")]
    public class Data
    {
        [XmlElement("data")]
        public OptionsData Options { get; set; }
    }
    
    public class OptionsData
    {
        [XmlAttribute("label")]
        public string Label { get; set; }
    
        [XmlAttribute("min")]
        public string Min { get; set; }
    
        [XmlAttribute("max")]
        public string Max { get; set; }
    
        [XmlElement("option")]
        public List<GeneralOptions> Items { get; } = new List<GeneralOptions>();
    }
    
    public class GeneralOptions
    {
        [XmlElement("id")]
        public string Id { get; set; }
    
        [XmlElement("name")]
        public string Name { get; set; }
    }
    

    【讨论】:

    • (对于最初感到困惑的其他人,Data 类模拟&lt;root&gt; 元素,OptionsData 类模拟&lt;data&gt; 元素)
    【解决方案2】:

    我建议使用xmltocsharp 或任何其他工具在几秒钟内将 XML 转换为 C# 模型...(消除所有手动错误)

    正如@canton7 所说,另一个简单的方法是使用Visual Studio: Edit -&gt; Paste Special -&gt; Paste XML As Classes

    [XmlRoot(ElementName="option")]
    public class Option {
        [XmlElement(ElementName="id")]
        public string Id { get; set; }
        [XmlElement(ElementName="name")]
        public string Name { get; set; }
    }
    
    [XmlRoot(ElementName="data")]
    public class Data {
        [XmlElement(ElementName="option")]
        public List<Option> Option { get; set; }
        [XmlAttribute(AttributeName="label")]
        public string Label { get; set; }
        [XmlAttribute(AttributeName="min")]
        public string Min { get; set; }
        [XmlAttribute(AttributeName="max")]
        public string Max { get; set; }
    }
    
    [XmlRoot(ElementName="root")]
    public class Root {
        [XmlElement(ElementName="data")]
        public Data Data { get; set; }
    }
    

    【讨论】:

    • (请注意,Visual Studio 中内置了一个:编辑 -> 选择性粘贴 -> 将 XML 粘贴为类。不过,它会生成非常冗长的 C#)
    猜你喜欢
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2012-01-05
    • 1970-01-01
    相关资源
    最近更新 更多