[英]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: 笔记:
When reading, the complete XML is loaded into an XElement
member which can be queried using LINQ to XML . 读取时, XElement
完整的XML加载到XElement
成员中,可以使用LINQ to XML查询该成员。 As a result the original formatting may get lost. 结果,原始格式可能会丢失。
IXmlSerializable
is tricky to implement correctly. IXmlSerializable
很难正确实现。 See Proper way to implement IXmlSerializable? 请参见实现IXmlSerializable的正确方法? and How to Implement IXmlSerializable Correctly for some tips on how to do it. 以及有关如何正确实现IXmlSerializable的技巧。
The known properties Someattributea
, Someattributeb
and Someattributec
now become surrogate lookups into the underlying XElement
. 已知属性Someattributea
, Someattributeb
和Someattributec
现在成为对基础XElement
替代查找。
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; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.