0

I have a xml schema in the form of

<?xml version="1.0" encoding="UTF-8"?>
<project ref="edward" name="Edward(A)">
<desc/>
<Zones>
   <Zone ref="1" name="Zone1"/>
   <Zone ref="2" name="Zone2"/>
   <Zone ref="3" name="Zone3"/>
   <Zone ref="4" name="Zone4"/>
</Zones>
</project>

I am trying to extract all the Zones value using Xml to Linq (not an expert)

I tried

 string xmlString = System.IO.File.ReadAllText("..\\..\\..\\v1.xml");

 XDocument xdoc = new XDocument();
 xdoc=XDocument.Parse(xmlString);

 var ele = xdoc.Descendants("Zones")
               .Select(x => (string)x.Element("name"))
               .FirstOrDefault();
 // this is null



var result = xdoc.Element("project").Descendants("Zones").Descendants("Zone");
foreach (var item in result)
{
      Console.WriteLine(item.name); //what should be here
}
Rohit
  • 10,056
  • 7
  • 50
  • 82
  • @JohnG The value obtained is I dont know how to split it. Or is there a way I can get all off them into list – Rohit Feb 27 '21 at 12:28
  • Have you tried... `Console.WriteLine(item.Attribute("name").Value);` – JohnG Feb 27 '21 at 12:39

3 Answers3

1

You could add the items to a list or using a Dictionary<int, string> may look something like...

Dictionary<int, string> Zones = new Dictionary<int, string>();
foreach (var item in result) {
  int.TryParse(item.Attribute("ref").Value, out int value);
  Zones.Add(value, item.Attribute("name").Value);
  Console.WriteLine(item.Attribute("name").Value);
  Console.WriteLine(item.Attribute("ref").Value);
}

Another approach using two simple Classes…

Looking closer, I am betting using a couple of classes and the System.Xml.Serialization; library may make this easier. Given the XML file. One Class appears obvious… called a Zone object with the int and string properties. Then another Class we could call ZoneProject.

The ZoneProject Class would have three (3) properties. In this case two string properties called Ref and Name, and a List<Zone> of Zone objects called Zones. The bare minimum of these two classes may look something like…

The Zone Class

public class Zone {
  [XmlAttribute("ref")]
  public int Ref { get; set; }
  
  [XmlAttribute("name")]
  public string Name { get; set; }
}

The ZoneProject Class

[XmlRoot("project")]
public class ZoneProject {
  [XmlAttribute("ref")]
  public string Ref { get; set; }
  
  [XmlAttribute("name")]
  public string Name { get; set; }
  
  [XmlArray("Zones")]
  public List<Zone> Zones { get; set; }
}

To help “deserialize” the XML we added additional qualifiers to help mate the XML element/attributes to the particular property of each class. The XmlRoot is the base class ZoneProject with the XmlAttributes and the collection of Zone objects using the XmlArray qualifier. This property will be a List<Zone> collection. The same follows for the Zone Class.

With this set up, we can use the System.Xml.Serialization; library and deserialize the XML file into a single ZoneProject object. Something like…

string filePath = @"PathToYourXML_File\file.xml";
XmlSerializer serializer = new XmlSerializer(typeof(ZoneProject));
ZoneProject TheZoneProject;
using (FileStream fs = File.OpenRead(filePath)) {
  TheZoneProject = (ZoneProject)serializer.Deserialize(fs);
}

It should be noted, that the answer from @Enyra on the SO question How to read XML file into List<>? …was helpful in the answer above.

I hope this makes sense.

JohnG
  • 9,259
  • 2
  • 20
  • 29
0

Please check your xml file path. I think that , problem here.

 string xmlString = System.IO.File.ReadAllText(dicorrectPath);
0

You can collect you zones attributes with Linq:

var result = xdoc.Element("project").Descendants("Zones").Descendants("Zone");
var zonesAtributes = result.Select(x => 
    new 
    { 
        name = x.Attribute("name").Value, 
        @ref = x.Attribute("ref").Value 
    }).ToArray();
Badj
  • 71
  • 5