[英]C# XML deserialize self closing raw element
我需要處理一些 XML 輸入,在某些標簽中有 HTML 代碼。 對於這些標簽,我希望原始內容稍后進行處理。 我遵循了這個答案並使用了在大多數情況下都可以正常工作的XmlElement
。 我面臨的唯一問題是自動關閉標簽。
[Serializable]
public class Root
{
public XmlElement Description { get; set; }
public string Name { get; set; }
}
var serializer = new XmlSerializer(typeof(Root));
var obj1 = serializer.Deserialize(new StringReader(@"<Root><Description><p>test</p></Description><Name>Test</Name></Root>"));
// Description: "Element, Name=\"p\""
// Name: "Test"
var obj2 = serializer.Deserialize(new StringReader(@"<Root><Description></Description><Name>Test</Name></Root>"));
// Description: null
// Name: "Test"
var obj3 = serializer.Deserialize(new StringReader(@"<Root><Description/><Name>Test</Name></Root>"));
// Description: "Element, Name=\"Name\""
// Name: null
obj1
和obj2
沒問題( obj2.Description == ""
會更好)但是在obj3
中Description
成員是貪婪的並且包含Name
部分。
這個問題有解決方法嗎?
一種可能的解決方法是為Description
屬性聲明自定義 class,使用[XmlAnyElement] 屬性匹配元素內的任何內容:
public class Root
{
public Description Description { get; set; }
public string Name { get; set; }
}
public class Description
{
[XmlAnyElement]
public List<XmlElement> Content { get; set; }
}
唯一的缺點是這不適用於混合內容。 換句話說,這將很好地反序列化:
<Description><p>test</p></Description>
但這不會,僅反序列化<span>
:
<Description>some <span>other</span> text</Description>
如果您需要混合內容,請在Description
class 上實施IXmlSerializable
。
但是,它確實適用於<Description/>
。 話雖如此,我同意@MarcGravell 的觀點,即它是XmlSerializer
中的一個錯誤,應該報告。
按照建議,我報告了這個問題。
我現在使用此代碼來解決此問題:
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
public class Program
{
public static void Main()
{
var serializer = new XmlSerializer(typeof(Root));
var obj1 = serializer.Deserialize(new StringReader(@"<Root><Description><p>test</p></Description><Name>Test</Name></Root>"));
Console.WriteLine(obj1); // Description: <p>test</p> / Name: Test
var obj2 = serializer.Deserialize(new StringReader(@"<Root><Description></Description><Name>Test</Name></Root>"));
Console.WriteLine(obj2); // Description: / Name: Test
var obj3 = serializer.Deserialize(new StringReader(@"<Root><Description/><Name>Test</Name></Root>"));
Console.WriteLine(obj3); // Description: / Name: Test
}
public class Root
{
public HtmlElement Description { get; set; }
public string Name { get; set; }
public override string ToString() => $"Description: {Description.Content} / Name: {Name}";
}
public class HtmlElement : IXmlSerializable
{
public string Content { get; set; } = "";
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
if (!reader.IsEmptyElement && reader is XmlTextReader xtr)
{
Content = xtr.ReadInnerXml();
}
}
public void WriteXml(XmlWriter writer) => throw new NotImplementedException();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.