Xmlserializer для C # объекта, хранить оригинальный элемент XML - PullRequest
0 голосов
/ 12 мая 2018

Возможно ли сохранить исходный элемент XML в классе C #, например?

Оригинальный XML:

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

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="" />

    }

}

Я понимаю, что могу снова десериализовать класс, но некоторые объекты XML неизвестны во время разработки.

1 Ответ

0 голосов
/ 13 мая 2018

Если вам действительно нужно захватить все, что связано с элементом <data /> , включая имя элемента и само пространство имен , в строковый литерал, вам потребуется реализовать IXmlSerializable и сериализоватьваш Data тип вручную.Например, вот реализация прототипа:

[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;
        }
    }
}

Примечания:

  • При чтении полный XML-код загружается в элемент XElement, который можно запрашиватьиспользуя LINQ to XML .В результате исходное форматирование может быть потеряно.

  • IXmlSerializable сложно реализовать правильно.См. Правильный способ реализации IXmlSerializable? и Как правильно реализовать IXmlSerializable для получения нескольких советов о том, как это сделать.

  • Известные свойства Someattributea, Someattributeb и Someattributec теперь становятся суррогатными поисками в базовом XElement.

Рабочая .Net fiddle здесь .

Если, с другой стороны, вам нужно только захватить неизвестные элементы, атрибуты и текстовое содержимое, вы можете использовать [XmlAnyAttribute], [XmlAnyElement] и [XmlText] (первые два из которых предлагаются в этом ответе до XmlSerializer, эквивалентный IExtensibleDataObject by Марк Гравелл ).Этот подход приводит к гораздо более простой версии 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; }
}

Работает .Net fiddle # 2 здесь .

...