XML 反序列化:在单个 属性 上使用 XmlAttribute 和 XmlText
XML Deserialization: Use XmlAttribute and XmlText on a single property
我正在尝试将值反序列化为 XmlAttribute
或 XmlText
,以获得相等的 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);
}
我认为这种方法和相同的命名迟早会误导您。
我正在尝试将值反序列化为 XmlAttribute
或 XmlText
,以获得相等的 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);
}
我认为这种方法和相同的命名迟早会误导您。