【问题标题】:C# Deserialize inner XML to stringC# 将内部 XML 反序列化为字符串
【发布时间】:2016-11-15 23:29:41
【问题描述】:

我有以下 XML:

<MyType>
  <MyProperty1>Value 1</MyProperty1>
  <MyProperty2>Value 2</MyProperty2>
  <MyNestedXml>
    <h1>Heading</h1>
    <p>Lorum</p>
    <p>Ipsum</p>
  </MyNestedXml>
</MyType>

这可以通过创建类和添加属性在 C# 中反序列化为 XML,如下所示:

[Serializable]
public class MyType
{
    [XmlElement("MyProperty1")
    public string MyProperty1 { get; set; }

    [XmlElement("MyProperty2")
    public string MyProperty2 { get; set; }

    [XmlIgnore]
    public string MyNestedXml { get; set; }
}

但是,&lt;MyNestedXml&gt; 元素中的内部 XML 会有所不同,并且不遵循我可以使用属性有效映射的一致结构。

很遗憾,我无法控制 XML 结构。

我尝试使用具有 XmlNode 类型的 [XmlElement("MyNestedXml") 但这会导致第一个子节点被反序列化,而不是整个内部 XML。

我也尝试过反序列化为一种字符串,但会引发 InvalidOperationException:

“非预期的节点类型元素。ReadElementString 方法只能在内容简单或为空的元素上调用。”

问题在于 MyNestedXml 元素的内容有时可能是 Elements 数组,但有时可能是简单或空内容。

理想情况下,我可以使用不同的序列化属性(例如 [XmlAsString])来完全跳过序列化并按原样分配内部 XML。

预期的结果将是一个 MyType 类型的类,它具有属性 MyProperty1 = "Value 1"、属性 MyProperty2 = "Value 2" 和属性 MyNestedXml = "&lt;h1&gt;Heading&lt;/h1&gt;&lt;p&gt;Lorum&lt;/p&gt;&lt;p&gt;Ipsum&lt;/p&gt;"。

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

    使用XmlAnyElement 属性使其成为XmlElement 属性,序列化程序将反序列化任意XML 结构。

    [XmlRoot("MyType")]
    public class MyType
    {
        [XmlElement("MyProperty1")]
        public string MyProperty1 { get; set; }
    
        [XmlElement("MyProperty2")]
        public string MyProperty2 { get; set; }
    
        [XmlAnyElement("MyNestedXml")]
        public XmlElement MyNestedXml { get; set; }
    }
    

    【讨论】:

    • 刚刚试了一下,它可以公开一个 XmlElement,我随后可以调用 .InnerXml 来获取我想要的字符串值。
    【解决方案2】:

    我已经设法解决了这个问题......

    我创建了一个类来反序列化:

    public class RichText : IXmlSerializable
    {
        public string Raw { get; set; }
    
        public XmlSchema GetSchema()
        {
            return null;
        }
    
        public void ReadXml(XmlReader reader)
        {
            Raw = reader.ReadInnerXml();
        }
    
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteString(Raw);
        }
    }
    

    这允许我有以下类定义:

    [Serializable]
    public class MyType
    {
        [XmlElement("MyProperty1")
        public string MyProperty1 { get; set; }
    
        [XmlElement("MyProperty2")
        public string MyProperty2 { get; set; }
    
        [XmlElement("MyNestedXml")]
        public RichText MyNestedXml { get; set; }
    }
    

    我现在可以使用InstanceOfMyType.MyNestedXml.Raw 将内部 XML 获取为字符串。如果我这样选择,我可以覆盖 RichText.ToString() 方法以返回 Raw 属性。

    希望这对将来的其他人有所帮助。

    【讨论】:

      【解决方案3】:

      如果 XML 的结构不一致,您将不得不使用 XMLReader。

      我建议您查看此链接以了解有关如何使用 XMLReader 的递归模式。它也可能是解析 XML 的最快方法。

      Traverse a XML using Recursive function

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多