XML 反序列化:如果存在两个元素,我如何才能优先于另一个元素绑定到一个元素?

问题描述 投票:0回答:2

我需要反序列化包含以下三种形式之一的元素的 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,否则使用存在的那个。

我无法想出解决方案。

c# xml xmlserializer xml-deserialization ixmlserializable
2个回答
1
投票

试试这个。

   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);
        }

    }

1
投票

有很多方法可以解决您的问题。

其中之一是使用

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; }
}
© www.soinside.com 2019 - 2024. All rights reserved.