简体   繁体   English

Xmlserializer转换为C#对象,存储原始XML元素

[英]Xmlserializer to C# object, store original XML element

Is it possible to store the original XML element in a C# class, for example? 例如,是否可以将原始XML元素存储在C#类中?

Original XML: 原始XML:

 <data someattributea="" someattributeb="" someattributec="" />

C# C#

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
    [XmlRoot(ElementName="data")]
    public class Data {
        [XmlAttribute(AttributeName="someattributea")]
        public string Someattributea { get; set; }
        [XmlAttribute(AttributeName="someattributeb")]
        public string Someattributeb { get; set; }
        [XmlAttribute(AttributeName="someattributec")]
        public string Someattributec { get; set; }

        public sourceXML { get; set; }    //this would return <data someattributea="" someattributeb="" someattributec="" />

    }

}

I understand I could deserialize the class again but some XML objects are unknown at design time. 我知道我可以再次反序列化该类,但是某些XML对象在设计时是未知的。

If you really need to capture everything about the <data /> element including the element name and namespace itself into a string literal, you will need to implement IXmlSerializable and serialize your Data type manually. 如果确实需要将有关<data />元素的所有信息( 包括元素名称和名称空间本身)捕获为字符串文字,则需要实现IXmlSerializable并手动序列化Data类型。 For instance, here is a prototype implementation: 例如,这是一个原型实现:

[XmlRoot(ElementName = ElementName)]
public class Data : IXmlSerializable
{
    public const string ElementName = "data";

    XElement element = new XElement((XName)ElementName);

    public string Someattributea
    {
        get { return (string)element.Attribute("someattributea"); }
        set { element.SetAttribute("someattributea", value); }
    }

    public string Someattributeb
    {
        get { return (string)element.Attribute("someattributeb"); }
        set { element.SetAttribute("someattributeb", value); }
    }

    public string Someattributec
    {
        get { return (string)element.Attribute("someattributec"); }
        set { element.SetAttribute("someattributec", value); }
    }

    public string SourceXML
    {
        get
        {
            return element.ToString();
        }
        set
        {
            if (value == null)
                throw new ArgumentNullException();
            element = XElement.Parse(value);
        }
    }

    #region IXmlSerializable Members

    public XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        reader.MoveToContent();
        element = (XElement)XNode.ReadFrom(reader);
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (var attr in element.Attributes())
            writer.WriteAttributeString(attr.Name.LocalName, attr.Name.NamespaceName, attr.Value);
        foreach (var child in element.Elements())
            child.WriteTo(writer);
    }

    #endregion
}

public static class XElementExtensions
{
    public static void SetAttribute(this XElement element, XName attributeName, string value)
    {
        var attr = element.Attribute(attributeName);
        if (value == null)
        {
            if (attr != null)
                attr.Remove();
        }
        else
        {
            if (attr == null)
                element.Add(new XAttribute(attributeName, value));
            else
                attr.Value = value;
        }
    }
}

Notes: 笔记:

Working .Net fiddle here . 正在工作的.Net 在这里摆弄。

If, on the other hand, you only need to capture unknown elements, attributes and text content, you can use [XmlAnyAttribute] , [XmlAnyElement] and [XmlText] (the first two of which are suggested in this answer to XmlSerializer equivalent of IExtensibleDataObject by Marc Gravell ). 另一方面,如果您只需要捕获未知的元素,属性和文本内容,则可以使用[XmlAnyAttribute][XmlAnyElement][XmlText] (在与IExtensibleDataObject等效的XmlSerializer的 答案中建议使用前两个) 马克·格雷夫Marc Gravell ))。 This approach results in a much simpler version of Data : 这种方法产生了一个简单得多的Data版本:

[XmlRoot(ElementName = "data")]
public class Data
{
    [XmlAttribute(AttributeName = "someattributea")]
    public string Someattributea { get; set; }
    [XmlAttribute(AttributeName = "someattributeb")]
    public string Someattributeb { get; set; }
    [XmlAttribute(AttributeName = "someattributec")]
    public string Someattributec { get; set; }

    [XmlAnyAttribute]
    public XmlAttribute[] Attributes { get; set; }

    [XmlAnyElement]
    [XmlText] // Captures mixed content at the root level as well as child elements.
    public XmlNode[] ChildNodes { get; set; }
}

Working .Net fiddle #2 here . 在这里工作.Net小提琴#2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM