XmlElement按属性筛选
本文关键字:筛选 属性 XmlElement | 更新日期: 2023-09-27 17:54:21
背景:我有一个简单的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");
}
}
}
分两步做怎么样?首先,您可以在没有任何逻辑的情况下反序列化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#电源创建所需的模型:
public class DeserializedAndNormilizedObject
{
public IEnumerable<Division> Divisions { get; set; }
public IEnumerable<Division> WalletDivisions { get; set; }
}
var obj = new DeserializedAndNormilizedObject();
var devisionsSet = result.DivisionSets.FirstOrDefault(x => x.Name == "divisions");
if (devisionsSet != null)
{
obj.Divisions = devisionsSet.Divisions;
}
// Same for walletDivisions
并且您将作为反序列化的结果返回DeserializedAndNormilizedObject
。