我正在嘗試將一些 xml 反序列化為 C# 物件。訣竅在很大程度上是,我知道這個物件會是什么樣子。然而,這是一個具有動態元素的孩子。
(這里是一個例子)
<measurement>
<Time>2021-02-02</Time>
<ID>1</ID>
<LeftWheel>
<ValuesRead>
<DynamicValue>12.3</DynamicValue>
<DynamicValue2>2.3</DynamicValue2>
<DynamicValue4>1.3</DynamicValue4>
<DynamicValue3>10.3</DynamicValue3>
</ValuesRead>
</LeftWheel>
<RightWheel>
<ValuesRead>
<DynamicValue>12.3</DynamicValue>
<DynamicValue2>2.3</DynamicValue2>
<DynamicValue6>1.3</DynamicValue6>
<DynamicValue10>10.3</DynamicValue10>
</ValuesRead>
</RightWheel>
</measurement>
在這個 XML 中Measurement,Time、 和ID總是在物件中。和元素總是與 一起出現LeftWheel,但子元素是動態的,可以是任何東西。RightWheelValuesReadValuesRead
我嘗試制作一個 C# 物件來反映大部分結構,然后使用XmlSerializer.UnknownElement來獲取元素中的未知元素ValuesRead,但我無法將其鏈接到上面的父級以知道它是否在LeftWheelor上RightWheel。
XmlSerializer serializer = new XmlSerializer(typeof(FVISSiteEvent));
serializer.UnknownElement = UnknownElementFound;
有沒有一種方法可以將LeftWheel和RightWheel類定義為動態的序列化,而其他類不是動態的?
uj5u.com熱心網友回復:
您應該能夠使用UnknownElementFound事件來手動處理序列化的這些方面。請參閱:序列化未知元素名稱的 XML 陣列
其他選項可能是指定您希望看到的XmlElementAtrribute修飾屬性的型別,如果它們沒有被反序列化,它們將只是空的。
還有IXmlSerializable在您的班級中實施并完全控制反序列化的核選項。
uj5u.com熱心網友回復:
使用自定義序列化器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Xml.Schema;
namespace ConsoleApplication16
{
class Program
{
const string INPUT_FILENAME = @"c:\temp\test.xml";
const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(INPUT_FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Measurement));
Measurement measurement = (Measurement)serializer.Deserialize(reader);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME,settings);
serializer.Serialize(writer, measurement);
}
}
[XmlRoot("measurement")]
public class Measurement
{
public DateTime Time { get; set; }
public int ID { get; set; }
[XmlArray("LeftWheel")]
[XmlArrayItem("ValuesRead")]
public List<Wheel> leftWheel { get; set; }
[XmlArray("RightWheel")]
[XmlArrayItem("ValuesRead")]
public List<Wheel> rightWheel { get; set; }
}
public class Wheel : IXmlSerializable
{
List<decimal> values { get; set; }
// Xml Serialization Infrastructure
public void WriteXml(XmlWriter writer)
{
int count = 0;
XElement valuesRead = new XElement("ValuesRead");
for (int i = 0; i < values.Count; i )
{
valuesRead.Add(new XElement("ValuesRead" (i == 0? "" : i.ToString()), values[i]));
}
writer.WriteRaw(valuesRead.ToString());
}
public void ReadXml(XmlReader reader)
{
XElement values = (XElement)XElement.ReadFrom(reader);
this.values = values.Elements().Where(x => x.Name.LocalName.StartsWith("DynamicValue")).Select(x => (decimal)x).ToList();
}
public XmlSchema GetSchema()
{
return (null);
}
}
}
uj5u.com熱心網友回復:
除了使用自定義 Xml 序列化來反序列化您的 xml 檔案之外,這里還有另一種使用Cinchoo ETL的方法- 一個以簡單方式處理它的開源庫(那些愿意嘗試的人!)
定義 POCO 類
public class Measurement
{
public DateTime Time { get; set; }
public int ID { get; set; }
[ChoXPath("LeftWheel/ValuesRead/*")]
public double[] LeftWheel { get; set; }
[ChoXPath("RightWheel/ValuesRead")]
public dynamic RightWheel { get; set; }
}
使用 ChoETL 反序列化
using (var r = ChoXmlReader<Measurement>.LoadText(xml)
.WithXPath("/")
)
{
foreach (var rec in r)
rec.Print();
}
小提琴示例:https ://dotnetfiddle.net/KtNvra
免責宣告:我是這個庫的作者。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/427396.html
