【问题标题】:XML Deserialization: Use XmlAttribute and XmlText on a single propertyXML 反序列化:在单个属性上使用 XmlAttribute 和 XmlText
【发布时间】:2021-12-01 00:08:21
【问题描述】:

我正在尝试将值反序列化为 XmlAttributeXmlText 以获取相同的 xml 标签。
反序列化时,两个选项都应该有效,并且两个选项最终都应该将一个值反序列化为一个类的相同属性。

基本上我的 xml 看起来像这样:

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

并给出类:

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

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

我希望“Item1”和“Item2”最终出现在各自 ArrayItems 的 Value 属性中。

我知道这样的事情是在用于 WPF 的 xaml 中完成的,例如,在定义 TextBlock 的 Text 属性时,我可以在 xml 标记内以及直接在 Text 属性内进行设置。即

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

我已经尝试了相应类属性的不同组合,但似乎最后一个最终覆盖了前一个,所以我只剩下两个选项之一。
此外,如果可以使用XmlSerializer 类,我更愿意这样做。

编辑: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;
}

这适用于我的情况。

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

【问题讨论】:

    标签: c# xml xml-serialization xmlserializer


    【解决方案1】:

    为什么不将节点值和属性值分开使用?

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

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

    【讨论】:

    • 我的要求是该值应该可以由单个属性访问。但是你给了我一个想法。根据您的 2 个属性,我可以实现一个私有字段,这两个属性都指向。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多