[英]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.