How Do I Use C# To Read XML Sub Elements

Hello.
I am having a problem trying to read sub elements in an XML document.  Here is a simple example of the XML document I am currently able to read:

<?xml version="1.0" encoding="utf-8"?>
<WorkTeams>
    <WorkTeam Name="BlueTeam">
        <HomeBase>Los Angeles</HomeBase>
        <Vehicles>35</Vehicles>
    </WorkTeam>
    <WorkTeam Name="RedTeam">
        <HomeBase>San Diego</HomeBase>
        <Vehicles>20</Vehicles>
    </WorkTeam>
</WorkTeams>

I am able to read the above simple XML document with the following c# code:

        private void ReadXMLVehicleInfo()
        {
            String HomeBase = "";
            String Vehicles = "";

            DataSet ds = new DataSet();
            ds.ReadXml("c:\\VehicleTeams.xml");

            DataRow[] drs = ds.Tables["WorkTeam"].Select("Name = 'BlueTeam' ");
            if (drs.Length != 0)
            {
                HomeBase = drs[0]["HomeBase"].ToString();
                Vehicles = drs[0]["Vehicles"].ToString();
            }
            else
            {
            }
        }

My problem begins when I tried to introduce an element, (VehicleMfgs), with sub elements, (VehicleMfg),such as in the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<WorkTeams>
    <WorkTeam Name="BlueTeam">
        <HomeBase>Los Angeles</HomeBase>
        <Vehicles>35</Vehicles>
        <VehicleMfgs>
            <VehicleMfg>Toyota</VehicleMfg>
            <VehicleMfg>Nissan</VehicleMfg>
            <VehicleMfg>Volvo</VehicleMfg>
        </VehicleMfgs>
    </WorkTeam>
    <WorkTeam Name="RedTeam">
        <HomeBase>San Diego</HomeBase>
        <Vehicles>20</Vehicles>
        <VehicleMfgs>
            <VehicleMfg>Ford</VehicleMfg>
            <VehicleMfg>Dodge</VehicleMfg>
            <VehicleMfg>Suzuki</VehicleMfg>
        </VehicleMfgs>
    </WorkTeam>
</WorkTeams>

How do I get a collection or list of the VehcleMfgs given that I know table will be WorkTeam and Name will be RedTeam?  The above code approach does not handle sub lists like the the one above with 3 different vehicle mfgs (i.e. Ford, Dodge, Suzuki).  Perhaps I should not be using a dataset or datatable.  Please advise if there is another way to do this with not much effort but while still using .NET XML classes.  
Thanks in advance.
LVL 1
zonkermanAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
joechinaConnect With a Mentor Commented:
XPathDocument xDoc = new XPathDocument(new StringReader(xml));
            XPathNavigator xNav = xDoc.CreateNavigator();
            XPathNodeIterator xi = xNav.Select(@"/WorkTeams/WorkTeam[@Name=""RedTeam""]/VehicleMfgs/VehicleMfg");
            List<string> result = new List<string>();
            while (xi.MoveNext())
            {
                result.Add(xi.Current.Value);
            }
0
 
Alexandre SimõesManager / Technology SpecialistCommented:
Where did the XML came from?
Why are you creating it's schema by hand?

The easiest way to do this is to create a type dataset with your schema. Fill the dataset with your data and serialize it (WriteXML). Reading it is as easy as ds.ReadXML.

What you're doing right now isn't a dataset, it's nested classes...
A colletion of a class  WorkTeams that have 3 public properties:
HomeBase (string)
Vehicles (int)
VehicleMfgs that is a collection of a class VehicleMfg.

So, or you use the XMLReader to loop through the nodes or you create a class hierarchy to map your structure... yet, I think it's much easier to use the dataset directly.

0
 
zonkermanAuthor Commented:
Hello AlexCode.
The XML is created by a c# utility that performs something like the following:

        private void WriteXMLConfigInfo()
        {            
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("    ");
            XmlWriter writer = XmlWriter.Create("c:\\VehicleTeams.xml", settings);
                // Write XML data.

            //Use automatic indentation for readability.
           // writer.Formatting = Formatting.Indented;

            //Write the XML delcaration.
            writer.WriteStartDocument();

            //Write the root element
            writer.WriteStartElement("WorkTeams");

            //Start an element
            writer.WriteStartElement("WorkTeam");

            //Add an attribute to the previously created element
            writer.WriteAttributeString("Name", "BlueTeam");

            //add sub-elements
            writer.WriteElementString("HomeBase", "Los Angeles");
            writer.WriteElementString("Vehicles", "35");
.......

The utility provides a gui for a user to setup information needed by an application.  I need for the user to create the necessary information with a gui rather than expect them to edit an xml file by hand.  The utility works fine so far but now I need to deal with a list of sub elements as I described in the first note.  I have used an XMLReader before but I am looking for a way to directly access the section of the XML file rather than have to iterate through checking for the right area.  That is why I was using the instance of a Dataset class followed by an instance collection of DataRow class so I could use the "select" filter ability.  I'm sure this could be done with LINQ but I won't be up to speed on LINQ for a while.  So I am seeking a way to have my C# code jump the the relevant area of the XML document then extract the information that pertains to that section (data row) for a given team name.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
zonkermanAuthor Commented:
For now I have found that if I change the XML format to the following then the original C# code I have will handle the list of vehicle manufacturers:

<?xml version="1.0" encoding="utf-8"?>
<WorkTeams>
    <WorkTeam Name="BlueTeam">
        <HomeBase>Los Angeles</HomeBase>
        <Vehicles>35</Vehicles>
        <VehicleMfgs>Toyota,Nissan,Volvo</VehicleMfg>
    </WorkTeam>
    <WorkTeam Name="RedTeam">
        <HomeBase>San Diego</HomeBase>
        <Vehicles>20</Vehicles>
        <VehicleMfgs>Ford,Dodge,Suzuki</VehicleMfgs>
    </WorkTeam>
</WorkTeams>

Unfortunately with the new format I have to parse out the list of vehicle manufacturers which are now delimited by commas rather than listed as separate elements as before.  If anyone can provide a way to access the VehicleMfgs as I had listed in the first example which was as follows:
<VehicleMfgs>
        <VehicleMfg>Ford</VehicleMfg>
        <VehicleMfg>Dodge</VehicleMfg>
        <VehicleMfg>Suzuki</VehicleMfg>
  </VehicleMfgs>

then please provide an example of how it can be done.  Thanks in advance.

0
 
zonkermanAuthor Commented:
Hello joechina.
Thank you for your solution.  Your sample code is direct, to the point, and exactly what I was looking for.  Good Job!

0
 
zonkermanAuthor Commented:
Thanks joechina.  Your solution is direct, to the point, and exactly what I was hoping for.  Good Job!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.