The position of the object (row, column) in XML after deserialization.

How can I get the position in the xml file of the 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>

Mapping XMLto Objects C #

[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); 
+4
source share
2 answers

Another, simpler approach: let the deserializer do the work.

  • Add LineInfoand LinePositionproperties of all classes for which you would like to have information about the location:

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

  • Download XDocumentwith LoadOptions.SetLineInfo.

  • Add attributes LineInfoand LinePositionall elements:

    foreach (var element in xdoc.Descendants())
    {
         var li = (IXmlLineInfo) element;
         element.SetAttributeValue("LineNumber", li.LineNumber);
         element.SetAttributeValue("LinePosition", li.LinePosition);
     }
    
  • LineInfo LinePosition.

:

  • , , , .
  • .
+6

. :

  • IXmlSerializable. , .

  • XmlReader, XmlReader static , , , XmlReader . : static; .

, , , , .

, .

  • XML :

    XDocument xdoc = XDocument.Parse(xml, LoadOptions.SetLineInfo);
    
  • xdoc (, NewId), , . a 0, a 1 ..

  • , , ( AddressDetails), NewId, :

        [XmlAttribute]
        public int NewId { get; set; }
    

    , , xsd.exe , , partial (, a partial class foo : MyBaseClassElement { } - ).

  • , , XElement, , NewId. ( , List<XElement>, XElement, NewId .)

  • XElement IXmlLineInfo .

  • , (, Number ) , XElement, NewId (, AdressDetails), :

    XElement element = ...;
    XNode descendant = element.Descendants(childElementOrAttributetName).FirstOrDefault();
    return descendant as IXmlLineInfo;
    

:

  • .
  • .
0

Source: https://habr.com/ru/post/1530015/


All Articles