XML 反序列化:在单个 属性 上使用 XmlAttribute 和 XmlText

XML Deserialization: Use XmlAttribute and XmlText on a single property

我正在尝试将值反序列化为 XmlAttributeXmlText,以获得相等的 xml 标签。
反序列化时,两个选项都应该有效,并且两个选项最终都应该将值反序列化为 class.

的相同 属性

基本上我的xml是这样的:

<ArrayTest>
  <ArrayItem>Item1</ArrayItem>
  <ArrayItem Value="Item2"/>
</ArrayTest>

并给出 classes:

public class ArrayTest
{
    [XmlElement(nameof(ArrayItem))]
    public ArrayItem[] Items { get; set; }
}

public class ArrayItem
{
    //[XmlAttribute]
    //[XmlText]
    public string Value { get; set; }
}

我希望“Item1”和“Item2”在各自 ArrayItems 的值 属性 中结束。

我知道在 xaml 中为 WPF 做了类似的事情,例如在定义 TextBlock 的 Text 属性 时,我可以在 xml 标签以及直接在文本 属性 中。即

<TextBlock Text="Sample text"/>
<TextBlock>
    Sample Text
<TextBlock/>

我已经尝试了相应 class 属性的不同组合,但似乎最后一个只是覆盖了前一个,所以我只剩下两个选项之一。
另外,如果可以使用 XmlSerializer Class.

,我更愿意

编辑: 受到 Auditive 的 回答的启发,我采用了这个:

public class ArrayItem
{
    [XmlAttribute(nameof(Value))]
    public string ValueAttribute
    {
        get => mValue;
        set => mValue = value;
    }

    [XmlText]
    public string Value
    {
        get => mValue;
        set => mValue = value;
    }
    
    private string mValue;
}

这适用于我的情况。

但是请注意,这不适用于序列化,因为这样两个属性都会被保存。

为什么不对节点值和属性值使用单独的属性?

public class ArrayItem
{
    [XmlAttribute("Value")]
    public string ValueAttribute { get; set; }
    [XmlText]
    public string Value { get; set; }
}

以这个例子:

static void Main(string[] args)
{
    ArrayTest arrayTest = new ArrayTest
    {
        Items = new ArrayItem[] 
        {
            new ArrayItem{ Value = "Item1" },
            new ArrayItem{ ValueAttribute = "Item2" }
        }
    };

    XmlSerializer serializer = new XmlSerializer(typeof(ArrayTest));
    using FileStream fs = new FileStream("MyFile.xml", FileMode.OpenOrCreate);
        serializer.Serialize(fs, arrayTest);
}

它会给你想要的输出:

<?xml version="1.0"?>
<ArrayTest>
    <ArrayItem>Item1</ArrayItem>
    <ArrayItem Value="Item2" />
</ArrayTest>

从文件反序列化也可以正常工作:

using (FileStream fs = new FileStream("H:\MyFile2.xml", FileMode.OpenOrCreate))
{
    ArrayTest deserializedArrayTest = formatter.Deserialize(fs) as ArrayTest;

    foreach (ArrayItem arrayItem in deserializedArrayTest.Items)
        Console.WriteLine("Array item value: " + arrayItem.Value + "\n" +
                          "Array \"Value\" attribute value: " + arrayItem.ValueAttribute);
}

我认为这种方法和相同的命名迟早会误导您。