[英]Alternative for deserializing XML with XmlSerializer
我正在編寫一個UWP應用程序,並希望將xml中的列表反序列化為對象列表:
<List>
<Element Name="A">
<SubElement Name="A1">
<Color> Blue </Color>
<Color> Red </Color>
</SubElement>
<SubElement Name="A2">
<Color> Blue </Color>
<Color> Green </Color>
</SubElement>
</Element>
<Element Name="B">
<SubElement Name="B1">
<Color> Yellow </Color>
<Color> Red </Color>
</SubElement>
<SubElement Name="B2">
<Color> Yellow </Color>
<Color> Green </Color>
</SubElement>
</Element>
<Element Name="C"/>
<SubElement Name="C1">
<Color> Purple </Color>
<Color> Red </Color>
</SubElement>
<SubElement Name="C2">
<Color> Purple </Color>
<Color> Green </Color>
</SubElement>
</Element>
</List>
這些類看起來像這樣:
public class Element
{
[XmlAttribute]
public string Name { get; set; }
[XmlElement("SubElement")]
public List<SubElement> _subelement { get; set; }
}
public class SubElement
{
[XmlElement("Color")]
public string Color{ get; set; }
[XmlAttribute("Name")]
public string Name { get; set; }
}
我的C#代碼如下所示:
XDocument doc = XDocument.Load("list.xml");
XElement node = doc.Descendants(XName.Get("List")).FirstOrDefault();
var serializer = new XmlSerializer(typeof(List<Element>), new XmlRootAttribute("List"));
var elementList = serializer.Deserialize(node.CreateReader()) as List<Element>;
在調試模式下,此應用程序正常工作 在發布模式下,我收到此線程中的PlatformNotSupportedException
錯誤。 我發現問題必須與項目設置中的Compile with .NET Native tool chain
選項有關。 但我找不到解決問題的辦法。
我的問題:上面顯示的代碼是否有一個簡單的替代方法可以將XML反序列化為對象,它不使用XmlSerializer並在UWP應用程序中工作?
在您重寫的問題中 ,您的XML似乎具有任意復雜性,並且具有元素和屬性的混合。 您正在尋找一種在不使用XmlSerializer
情況下自動反序列化此XML的方法,這基本上相當於編寫另一個XML序列化程序 。
由於這是非常重要的(並且超出了stackoverflow答案的范圍),因此一個快速的解決方法是將XML轉換為某些其他序列化程序識別的格式,並使用它。 可能性包括:
DataContractSerializer
。 此序列化程序用於XML反序列化,但不支持:
<Element /><Element/>
)作為沒有外部元素的集合。 因此,雖然可以使用此序列化程序將XML反序列化為某些適當的數據模型,但仍需要使用LINQ to XML進行大量預處理。
Json.NET 。 此序列化程序支持將XML轉換為JSON,如在JSON和XML之間轉換中所述 ,因此可能適合您的需要。
如果選擇選項#2,則可以按如下方式定義數據模型:
public class RootObject
{
[JsonConverter(typeof(SingleOrArrayConverter<Element>))]
public List<Element> Element { get; set; }
}
public class Element
{
[XmlAttribute]
[JsonProperty("@Name")]
public string Name { get; set; }
[XmlElement("SubElement")]
[JsonProperty("SubElement")]
[JsonConverter(typeof(SingleOrArrayConverter<SubElement>))]
public List<SubElement> _subelement { get; set; }
}
public class SubElement
{
[XmlElement("Color")]
[JsonConverter(typeof(SingleOrArrayConverter<string>))]
public List<string> Color { get; set; }
[XmlAttribute("Name")]
[JsonProperty("@Name")]
public string Name { get; set; }
}
並反序列化如下:
var doc = XDocument.Parse(xmlString);
// Convert the XDocument to an intermediate JToken hierarchy.
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter { OmitRootObject = true };
var rootToken = JObject.FromObject(doc, JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = { converter } }));
// Convert the JTOken to a RootObject
var rootObj = rootToken.ToObject<RootObject>();
筆記:
在您的問題中,您的SubElement
具有單個Color
屬性,但在XML中,每個<SubElement>
顯然有多個<Color>
元素。 因此我不得不將其更改為public List<string> Color { get; set; }
public List<string> Color { get; set; }
public List<string> Color { get; set; }
。
SingleOrArrayConverter<>
是從如何使用 Brian Rogers的 JSON.net處理同一屬性的單個項目和數組的 答案中逐字逐句采用的 。 需要處理將單個子節點轉換為JSON對象而不是JSON數組的情況。
工作.Net小提琴 。
鑒於您的問題的初始版本中顯示的XML:
<List>
<Element Name="A"/>
<Element Name="B"/>
<Element Name="C"/>
</List>
假設您的Element
類型如下:
public class Element
{
[XmlAttribute]
public string Name { get; set; }
}
然后這種類型非常簡單,您可以手動構建它,如下所示:
var list = doc
// Get the first elements named List
.Descendants("List").Take(1)
// Get all children of List named Element
.SelectMany(l => l.Elements("Element"))
// Get the attribute of Element named Name, cast its value to a string,
// and create a c# Element from it using the specified name.
.Select(e => new Element { Name = (string)e.Attribute("Name") } )
// Materialize as a List<Element>
.ToList();
這里我使用XAttribute
的顯式轉換運算符將Name
屬性轉換為字符串值。 XElement
還有顯式的轉換運算符 ,可以將元素值轉換為基元,例如string
, int
或可為空的DateTime
等。 如上所示,在填充ac#類型時可以使用這些運算符。
(切換到DataContractSerializer
並不容易,因為此序列化程序不支持開箱即用的XML屬性,這意味着您無論如何都必須執行某些操作。)
樣品工作.Net小提琴 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.