C# XmlElement按属性筛选

C# XmlElement按属性筛选,c#,xml,deserialization,xmlserializer,C#,Xml,Deserialization,Xmlserializer,背景: 我有一个简单的XML表,我不能更改,它由第三方提供,类和反序列化由我们维护 问题如何使xml正确反序列化,它显然需要以某种方式检查“name”属性以决定填充哪个属性,但就我的一生而言,我不记得如何进行此操作。 我们正在使用的当前序列化程序是“System.Xml.Serialization.XmlSerializer”,由于旧的、依赖的代码,我们无法更改它 XML <result> <rowset name="divisions" key="accountKey

背景: 我有一个简单的XML表,我不能更改,它由第三方提供,类和反序列化由我们维护

问题如何使xml正确反序列化,它显然需要以某种方式检查“name”属性以决定填充哪个属性,但就我的一生而言,我不记得如何进行此操作。 我们正在使用的当前序列化程序是“System.Xml.Serialization.XmlSerializer”,由于旧的、依赖的代码,我们无法更改它

XML

<result>
    <rowset name="divisions" key="accountKey" columns="accountKey,description">
      <row accountKey="1000" description="Division 1"/>
      <row accountKey="1001" description="Division 2"/>
      <row accountKey="1002" description="Division 3"/>
      <row accountKey="1003" description="Division 4"/>
      <row accountKey="1004" description="Division 5"/>
      <row accountKey="1005" description="Division 6"/>
      <row accountKey="1006" description="Division 7"/>
    </rowset>
    <rowset name="walletDivisions" key="accountKey" columns="accountKey,description">
      <row accountKey="1000" description="Wallet Division 1"/>
      <row accountKey="1001" description="Wallet Division 2"/>
      <row accountKey="1002" description="Wallet Division 3"/>
      <row accountKey="1003" description="Wallet Division 4"/>
      <row accountKey="1004" description="Wallet Division 5"/>
      <row accountKey="1005" description="Wallet Division 6"/>
      <row accountKey="1006" description="Wallet Division 7"/>
    </rowset>
</result>

课程

[Serializable]
[XmlRoot("result", IsNullable = false)]
public class TestClass
{
    [XmlElement("rowset")]
    public EveXmlRowCollection<Division> Divisions { get; set; }
    [XmlElement("rowset")]
    public EveXmlRowCollection<Division> WalletDivisions { get; set; }

    [Serializable]
    [XmlRoot("row")]
    public class Division
    {
        [XmlAttribute("accountKey")]
        public int AccountKey { get; set; }

        [XmlAttribute("description")]
        public string Description { get; set; }
    }
}
public class EveXmlRowCollection<T> : Collection<T>, IXmlSerializable 
{
    //... Other, Irrelevant implementations

    public void ReadXml(XmlReader reader) {
        var serializer = new XmlSerializer(typeof (T));
        if (!reader.IsStartElement()) return;
        RowSetMeta.Name = reader.GetAttribute("name");
        RowSetMeta.Key = reader.GetAttribute("key");
        RowSetMeta.Columns = reader.GetAttribute("columns");
        reader.ReadToDescendant("row");
        while (reader.Name == "row") {
            if (reader.IsStartElement()) {
                var row = (T) serializer.Deserialize(reader);
                Items.Add(row);
            }
            reader.ReadToNextSibling("row");
        }
    }
}
[可序列化]
[XmlRoot(“结果”,IsNullable=false)]
公共类TestClass
{
[XmlElement(“行集”)]
公共集合分区{get;set;}
[XmlElement(“行集”)]
公共收集钱包分区{get;set;}
[可序列化]
[XmlRoot(“行”)]
公共课组
{
[XmlAttribute(“accountKey”)]
public int AccountKey{get;set;}
[XmlAttribute(“说明”)]
公共字符串说明{get;set;}
}
}
公共类EveMlRowCollection:集合,IXmlSerializable
{
//…其他不相关的实现
公共void ReadXml(XmlReader){
var serializer=newxmlserializer(typeof(T));
如果(!reader.IsStartElement())返回;
RowSetMeta.Name=reader.GetAttribute(“名称”);
RowSetMeta.Key=reader.GetAttribute(“Key”);
RowSetMeta.Columns=reader.GetAttribute(“Columns”);
reader.ReadToDescendant(“行”);
while(reader.Name==“行”){
if(reader.IsStartElement()){
var row=(T)序列化程序。反序列化(读取器);
项目。添加(行);
}
reader.ReadToNextSibling(“行”);
}
}
}

分两步做怎么样?首先,无需任何逻辑即可反序列化xml。只需创建适当的模型:

[XmlRoot("result")]
public class Result
{
    [XmlElement("rowset")]
    public DivisionSet[] DivisionSets { get; set; }
}

public class DivisionSet
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("row")]
    public Division[] Divisions { get; set; }
}

public class Division
{
    [XmlAttribute("accountKey")]
    public int AccountKey { get; set; }

    [XmlAttribute("description")]
    public string Description { get; set; }
}
使用它们进行反序列化非常简单:

var serializer = new XmlSerializer(typeof(Result));
using (TextReader reader = new StringReader("...XML..."))
{
    var result = (Result)serializer.Deserialize(reader);
}
然后您可以使用C#power创建所需的模型:

公共类反序列化和规范化对象
{
公共IEnumerable除法{get;set;}
公共IEnumerable WalletDivisions{get;set;}
}
var obj=新的反序列化和规范化对象();
var divisionset=result.divisionset.FirstOrDefault(x=>x.Name==“divisions”);
如果(DevisionSet!=null)
{
对象分割=分割集分割;
}
//walletDivisions也是如此

作为反序列化的结果,您将返回
反序列化和normalizedObject

分两步执行如何?首先,无需任何逻辑即可反序列化xml。只需创建适当的模型:

[XmlRoot("result")]
public class Result
{
    [XmlElement("rowset")]
    public DivisionSet[] DivisionSets { get; set; }
}

public class DivisionSet
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("row")]
    public Division[] Divisions { get; set; }
}

public class Division
{
    [XmlAttribute("accountKey")]
    public int AccountKey { get; set; }

    [XmlAttribute("description")]
    public string Description { get; set; }
}
使用它们进行反序列化非常简单:

var serializer = new XmlSerializer(typeof(Result));
using (TextReader reader = new StringReader("...XML..."))
{
    var result = (Result)serializer.Deserialize(reader);
}
然后您可以使用C#power创建所需的模型:

公共类反序列化和规范化对象
{
公共IEnumerable除法{get;set;}
公共IEnumerable WalletDivisions{get;set;}
}
var obj=新的反序列化和规范化对象();
var divisionset=result.divisionset.FirstOrDefault(x=>x.Name==“divisions”);
如果(DevisionSet!=null)
{
对象分割=分割集分割;
}
//walletDivisions也是如此


作为反序列化的结果,您将返回
反序列化和normilizedObject

什么是
EveXmlRowCollection
?一个非常简单的自定义集合:公共类EveXmlRowCollection:Collection,IXmlSerializable{…}不确定你问了什么?什么是
EveXmlRowCollection
?一个非常简单的自定义集合:公共类EveXmlRowCollection:Collection,IXmlSerializable{…}不确定你问了什么?什么是
EveXmlRowCollection
?一个非常简单的自定义集合:公共类EveXmlRowCollection:Collection,IXmlSerializable{…}不确定你问了什么?否决,需要一个纯粹的“反序列化”方法,值列表中的列表效率非常低,代码也很糟糕。你的方法会奏效,是的,但这不是我想要的答案,谢谢你的尝试,但为什么它“非常低效”?它表示XML的结构。因为我必须使用2个属性来公开数据(WalletDivisions&Divisions),并且由于技术要求,我不允许使用第3个隐藏属性(或列表中的列表),所以我更新了答案。我的想法是,您将返回您想要的对象。当然,您不希望返回具有嵌套数组的对象。你只需要规范化反序列化的对象。向下投票,需要一个纯粹的“反序列化”方法,值列表中的列表效率非常低,代码也很糟糕。你的方法会奏效,是的,但这不是我想要的答案,谢谢你的尝试,但为什么它“非常低效”?它表示XML的结构。因为我必须使用2个属性来公开数据(WalletDivisions&Divisions),并且由于技术要求,我不允许使用第3个隐藏属性(或列表中的列表),所以我更新了答案。我的想法是,您将返回您想要的对象。当然,您不希望返回具有嵌套数组的对象。你只需要规范化反序列化的对象。向下投票,需要一个纯粹的“反序列化”方法,值列表中的列表效率非常低,代码也很糟糕。你的方法会奏效,是的,但这不是我想要的答案,谢谢你的尝试,但为什么它“非常低效”?它表示XML的结构。因为我必须使用2个属性来公开数据(WalletDivisions&Divisions),并且由于技术要求,我不允许使用第3个隐藏属性(或列表中的列表),所以我更新了答案。我的想法是,您将返回您想要的对象。当然,您不希望返回具有嵌套数组的对象。您只需规范化反序列化对象。