Xmlserializer to C# object, store original XML element

﹥>﹥吖頭↗ 提交于 2019-12-08 05:46:26

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. 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.

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). This approach results in a much simpler version of 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!