我需要反序列化包含以下三种形式之一的元素的 XML:
<Element1>xxx</Element1>
或
<Element2>xxx</Element2>
或
<Element1>xxx</Element1>
<Element2>xxx</Element2>
如果两者都存在,我需要优先使用 Element1 的值而不是 Element2。我怎样才能做到这一点?
我正在使用 System.Xml.Serialization 来解析 xml 这是我的财产
[XmlElement("Element1")]
[XmlElement("Element2")]
public string Data
{
get
{
return this.data;
}
set
{
this.data = value;
}
}
就我而言,如果两者都存在,我需要使用 Element1,否则使用存在的那个。
我无法想出解决方案。
试试这个。
public class Parent : IXmlSerializable
{
public string data { get; set; }
public void WriteXml(XmlWriter writer)
{
writer.WriteString(data);
}
public void ReadXml(XmlReader reader)
{
XElement node = (XElement)XElement.ReadFrom(reader);
XElement element1 = node.Element("Element1");
XElement element2 = node.Element("Element2");
if(element1 == null)
{
data = (string)element2;
}
else
{
data = (string)element1;
}
}
public XmlSchema GetSchema()
{
return (null);
}
}
有很多方法可以解决您的问题。
其中之一是使用
UnknownElement
事件。
using System.Xml.Serialization;
var ser = new XmlSerializer(typeof(Root));
ser.UnknownElement += Serializer_UnknownElement;
void Serializer_UnknownElement(object? sender, XmlElementEventArgs e)
{
var root = (Root)e.ObjectBeingDeserialized;
var elem = e.Element;
if (elem.Name == "Element1")
root.Data = elem.InnerText;
else if (elem.Name == "Element2" && root.Data == null)
root.Data = elem.InnerText;
}
using var fs = new FileStream("test.xml", FileMode.Open);
var root = (Root)ser.Deserialize(fs);
Console.WriteLine(root.Data);
public class Root
{
public string Data { get; set; }
}
另一种方法是使用自定义读取器来动态替换数据。
using System.Xml;
using System.Xml.Serialization;
var ser = new XmlSerializer(typeof(Root));
using var reader = new CustomXmlReader("test.xml");
var root = (Root)ser.Deserialize(reader);
Console.WriteLine(root.Data);
public class CustomXmlReader : XmlTextReader
{
public CustomXmlReader(string url) : base(url) { }
private bool dataRead;
public override string LocalName
{
get
{
if (base.LocalName == "Element1")
{
dataRead = true;
return "Data";
}
else if (base.LocalName == "Element2" && !dataRead)
return "Data";
return base.LocalName;
}
}
}
public class Root
{
public string Data { get; set; }
}