目标位置(行,列)的XML反序列化.NET后 [英] Object position (line, column) in XML after deserialization .NET
问题描述
我怎样才能得到一个XML标记的原始XML文件的位置后反序列化到使用XmlSerializer的.NET对象?
下面是一个例子 XML
< ArrayOfAddressDetails>
< AddressDetails>
&其中;数→4&所述; /数字与GT;
<街> ABC< /街>
<城市名>伯尔尼< /城市名>
< / AddressDetails>
< AddressDetails>
&其中;数→3&所述; /数字与GT;
<街> ABCD< /街>
<城市名>布拉格< /城市名>
< / AddressDetails>
< / ArrayOfAddressDetails>
XMLto C#对象映射
[XmlRoot(根)
公共类AddressDetails
{
[的XmlElement(数字)
公众诠释的HouseNo;
[的XmlElement(街道)
公共字符串StreetName;
[的XmlElement(城市名)]
公共字符串市;
}
期望的结果。
XmlSerializer的序列化=新的XmlSerializer(typeof运算(名单< AddressDetails>));
VAR列表= serializer.Deserialize(@C:\ Xml.txt)的名单,其中,AddressDetails取代;
//这就是我想要做的
//获取信息的财产市第二对象的来源列表
VAR位置= XmlSerializerHelper.GetPosition(O =>清单[1]。城市,@C:\ Xml.txt);
//应打印开头的行= 10,列= 8
Console.WriteLine(开头的行= {0},列= {1},position.Start.Line,position.Start.Column);
//应打印结尾行= 10,列= 35
Console.WriteLine(结尾行= {0},列= {1},position.End.Line,position.Start.Column);
//应打印型=的XmlElement,名称=城市名,值=布拉格
Console.WriteLine(XML信息类型= {0},名称= {1},值= {2},position.Type,position.Name,position.Value);
另外,更简单的办法:让解串器做的工作
-
添加
LineInfo
和LinePosition
属性,你会为其想有位置信息的所有类:[XmlRoot(根) 公共类AddressDetails { [XmlAttribute] 公众诠释LINENUMBER {获得;组; } [XmlAttribute] 公众诠释LinePosition {获得;组; } ... }
这当然可以通过继承来完成。
-
加载一个
的XDocument
与LoadOptions.SetLineInfo
。 -
添加
LineInfo
和LinePosition
属性的所有元素:的foreach(在xdoc.Descendants VAR元素()) { VAR力=(IXmlLineInfo)元; element.SetAttributeValue(行号,li.LineNumber); element.SetAttributeValue(LinePosition,li.LinePosition); }
-
反序列化将填充
LineInfo
和LinePosition
。
缺点:
- 仅适用于那些反序列化类,而不是简单的元素,而不是属性的元素行信息。
- 需要的属性添加到所有类别。
How can I get position in the original xml file of an xml tag after deserialization into a .NET object using XmlSerializer ?
Here is an example XML
<ArrayOfAddressDetails>
<AddressDetails>
<Number>4</Number>
<Street>ABC</Street>
<CityName>Bern</CityName>
</AddressDetails>
<AddressDetails>
<Number>3</Number>
<Street>ABCD</Street>
<CityName>Prague</CityName>
</AddressDetails>
</ArrayOfAddressDetails>
XMLto C# object mapping
[XmlRoot("Root")]
public class AddressDetails
{
[XmlElement("Number")]
public int HouseNo;
[XmlElement("Street")]
public string StreetName;
[XmlElement("CityName")]
public string City;
}
Desired result
XmlSerializer serializer = new XmlSerializer(typeof(List<AddressDetails>));
var list = serializer.Deserialize(@"C:\Xml.txt") as List<AddressDetails>;
// this is what I would like to do
// getting information to origin of the property City of the 2nd object in the list
var position = XmlSerializerHelper.GetPosition(o => list[1].City, @"C:\Xml.txt");
// should print "starts line=10, column=8"
Console.WriteLine("starts line={0}, column={1}", position.Start.Line, position.Start.Column);
// should print "ends line=10, column=35"
Console.WriteLine("ends line={0}, column={1}", position.End.Line, position.Start.Column);
// should print "type=XmlElement, name=CityName, value=Prague"
Console.WriteLine("xml info type={0}, name={1}, value={2}", position.Type, position.Name, position.Value);
Another, more simple approach: Let the deserializer do the work.
Add
LineInfo
andLinePosition
properties to all classes for which you would like to have position information:[XmlRoot("Root")] public class AddressDetails { [XmlAttribute] public int LineNumber { get; set; } [XmlAttribute] public int LinePosition { get; set; } ... }
This of course can be done by subclassing.
Load an
XDocument
withLoadOptions.SetLineInfo
.Add
LineInfo
andLinePosition
attributes to all elements:foreach (var element in xdoc.Descendants()) { var li = (IXmlLineInfo) element; element.SetAttributeValue("LineNumber", li.LineNumber); element.SetAttributeValue("LinePosition", li.LinePosition); }
Deserializing will populate
LineInfo
andLinePosition
.
Cons:
- Line information only for elements that are deserialized as class, not for simple elements, not for attributes.
- Need to add attributes to all classes.
这篇关于目标位置(行,列)的XML反序列化.NET后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!