反序列化.NET后的XML中的对象位置(行,列)

Hon*_*scz 5 .net c# xml

在使用XmlSerializer反序列化到.NET对象后,如何在xml标记的原始xml文件中获得位置?

这是一个示例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>
Run Code Online (Sandbox Code Playgroud)

XML到C#对象映射

[XmlRoot("Root")]
public class AddressDetails
{
    [XmlElement("Number")]
    public int HouseNo;
    [XmlElement("Street")]
    public string StreetName;
    [XmlElement("CityName")]
    public string City;
} 
Run Code Online (Sandbox Code Playgroud)

期望的结果

 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); 
Run Code Online (Sandbox Code Playgroud)

Mar*_*tin 7

另一个更简单的方法:让解串器完成工作.

  • 为要获得位置信息的所有类添加LineInfoLinePosition属性:

    [XmlRoot("Root")]
    public class AddressDetails
    {
        [XmlAttribute]
        public int LineNumber { get; set; }
    
        [XmlAttribute]
        public int LinePosition { get; set; }
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这当然可以通过子类化来完成.

  • 加载一个XDocumentLoadOptions.SetLineInfo.

  • 添加LineInfoLinePosition属性到所有元素:

    foreach (var element in xdoc.Descendants())
    {
         var li = (IXmlLineInfo) element;
         element.SetAttributeValue("LineNumber", li.LineNumber);
         element.SetAttributeValue("LinePosition", li.LinePosition);
     }
    
    Run Code Online (Sandbox Code Playgroud)
  • 反序列化将填充LineInfoLinePosition.

缺点:

  • 行信息仅适用于反序列化为类的元素,不适用于简单元素,不适用于属性.
  • 需要为所有类添加属性.