Sergey M
Sergey M

Reputation: 43

C# How to parse XML File

I'm having trouble with the following XML file:

 <?xml version="1.0" encoding="UTF-16" ?> 
 <Export>
  ...
  <PID No="5" OffsetY="5" OffsetX="16.25" TRef="-127471" />
  ...
  <PID No="5" OffsetY="12" OffsetX="42" TRef="-127476" />
  <PID No="5" OffsetY="10" OffsetX="63" TRef="-127477" />
  ...
  <Folder FolderType="1025">
   <CFolder DisplayName="DName">
    <Object OID="-127471" ObjectName="5" ObjectType="25" /> 
    ...
    <Object OID="-127476" ObjectName="6" ObjectType="25" /> 
    <Object OID="-127477" ObjectName="7" ObjectType="25" />
    ...
   </CFolder>
  </Folder>
  ... 

 </Export>

I need to select:

OffsetX OffsetY ObjectName
 16.25     5          5
 ...
 42        12         6
 63        10         7
 ...

where TRef=OID

Could someone help me? I get only the first row. This code is everything that i managed to do:

XDocument doc = XDocument.Load(FileName);
XElement pid = doc.Root.Element("PID");
IEnumerable<XAttribute> OffsXlist =
            from offX in pid.Attributes("OffsetX")
            select offX;
IEnumerable<XAttribute> OffsYlist =
            from offY in pid.Attributes("OffsetY")
            select offY;

Upvotes: 1

Views: 128

Answers (2)

Kevin D
Kevin D

Reputation: 485

        var xDocument = XDocument.Load(FileName);

        var pidNodes = xDocument.Descendants("PID");
        var pids = pidNodes.Select(x => new
        {
            OffsetX = x.Attribute("OffsetX").Value,
            OffsetY = x.Attribute("OffsetY").Value,
            TRef = x.Attribute("TRef").Value
        });

        var objectNodes = xDocument.Descendants("Object");
        var objects = objectNodes.Select(x => new
        {
            OID = x.Attribute("OID").Value,
            ObjectName = x.Attribute("ObjectName").Value,
            ObjectType = x.Attribute("ObjectType").Value
        });

        var result = pids.Select(x => new
        {
            OffsetX = x.OffsetX,
            OffsetY = x.OffsetY,
            ObjectName = objects.Single(o => o.OID == x.TRef).ObjectName
        });

I assumed there's always a single corresponding OID for a given TRef. If this is not the case, additional checks must be added where I put objects.Single(o => o.OID == x.TRef).ObjectName

Upvotes: 1

Rahul Singh
Rahul Singh

Reputation: 21795

Try this:-

var result = xdcoc.Descendants("PID")
          .Select(x => new
          {
              OffetX = (string)x.Attribute("OffsetX"),
              OffsetY = (string)x.Attribute("OffsetY"),
              ObjectName = x.Parent.Descendants("Object")
                           .Where(z => z.Attribute("OID").Value == 
                                                      x.Attribute("TRef").Value)
                            .Select(z => (string)z.Attribute("ObjectName"))
                            .FirstOrDefault()
           });

I am getting following output:-

enter image description here

Upvotes: 2

Related Questions