J_Gandrup
J_Gandrup

Reputation: 11

How do i extract specific attributes while iterating through an XML document (XML Parsing) using C#

I am new to c# and therefore I hope that some of you can help me with this problem:

I have a long XML-file that consists of multiple nodes and attributes. I am looking for a method on how to iterate through the XML document while being able to set up a method to extract certain attributes of interest and then store those attributes in a array (the goal is to visualize them afterwards by storing in collection).

I have tried solving this in multiple ways, like for example by using get Xpath, deserialization and so forth, Unfortunately none of them work out, especially that <TeamData> appears more than once.

The XML-file looks like this:

- <SoccerFeed TimeStamp="20190818T190845+0100">
  - <SoccerDocument Type="Result" detail_id="1" uID="f1059230">
     - <MatchData>
          - <TeamData Formation="433" Score="2" Side="Home" TeamRef="t239">
            <Booking Card="Yellow" CardType="Yellow" EventID="6020960" EventNumber="1141" Min="13" 
             Period="FirstHalf" PlayerRef="p112340" Reason="Foul" Sec="31" Time="14" 
             TimeStamp="20190818T171443+0100" uID="b239-1" />
            </TeamData> 
          - <TeamData TeamRef="t401" Side="Away" Score="1" Formation="433">
             <Booking TimeStamp="20190818T182120+0100" uID="b401-1" Period="SecondHalf" Time="64" 
              Sec="15" Reason="Foul" PlayerRef="p229218" Min="63" EventNumber="2648" 
              EventID="708326435" CardType="Yellow" Card="Yellow"/>
             </TeamData>
        </MatchData>
  </SoccerDocument

This is somewhat my idea at this point:

    int totalC;
    XmlDocument xmlDoc = new XmlDocument();
    string XMLpath = Directory.GetCurrentDirectory() + 
     @"File.xml";
    xmlDoc.Load(XMLpath);

    XmlNodeList Clist = xmlDoc.GetElementsByTagName("TimeStamp");
    totalC = Clist.Count;

    for (int i = 0; i < Clist.Count; i++)
    {
        Console.WriteLine(Clist[i].InnerText.ToString());
    }
    Console.WriteLine(Environment.NewLine);
    Console.WriteLine(totalC.ToString() + " hello");
    Console.ReadLine();

I hope that my question is clear enough, thank you in advance!

Upvotes: 1

Views: 576

Answers (2)

MBB
MBB

Reputation: 1685

You can do this easily with LINQ to XML

 var doc = XDocument.Load(@"Test.xml");

 var distinctResults = doc.Descendants("Booking")
                       .Select(element => element.Attribute("TimeStamp").Value)
                       .Distinct().ToArray();

Without LINQ to XML -

XmlDocument xmlDoc = new XmlDocument();
string XMLpath = @"Test.xml";
xmlDoc.Load(XMLpath);
List<string> attributes = new List<string>();          

XmlNodeList nodes = xmlDoc.GetElementsByTagName("Booking");
foreach (XmlElement n in nodes)
   {
      XmlAttributeCollection attributesData = n.Attributes;
      foreach (XmlAttribute at in atributesData)
         {
            if (at.LocalName.Contains("TimeStamp"))
               {
                   attributes.Add(at.Value);
               }
          }
    }

Upvotes: 2

jdweng
jdweng

Reputation: 34421

I think in this case you should be using Xml Serialization due to the number of properties and the arrays in the data

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Globalization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            StringReader sReader = new StringReader(xml);
            XmlReader xReader = XmlReader.Create(sReader);

            XmlSerializer serializer = new XmlSerializer(typeof(SoccerFeed));
            SoccerFeed soccerFeed = (SoccerFeed)serializer.Deserialize(xReader);


        }
    }
    public class SoccerFeed
    {
        private DateTime _TimeStamp { get; set; }
        [XmlAttribute]
        public string TimeStamp
        {
            get { return _TimeStamp.ToString("yyyyMMddTHHmmss+ffff"); }
            set { _TimeStamp = DateTime.ParseExact(value, "yyyyMMddTHHmmss+ffff", CultureInfo.InvariantCulture); }
        }


        public SoccerDocument SoccerDocument { get; set; }
    }
    public class SoccerDocument
    {

        [XmlAttribute]
        public int detail_id { get; set; }
        [XmlAttribute]
        public string uID { get; set; }

        [XmlArray("MatchData")]
        [XmlArrayItem("TeamData")]
        public List<TeamData> teamData { get; set; }
    }
    public class TeamData
    {
        [XmlAttribute]
        public int Formation { get; set; }
        [XmlAttribute]
        public int Score { get; set; }
        [XmlAttribute]
        public string Side { get; set; }
        [XmlAttribute]
        public string TeamRef { get; set; }

        public Booking Booking { get; set; } 
    }
    public class Booking
    {
        [XmlAttribute]
        public string Card { get; set; }
        [XmlAttribute]
        public string CardType { get; set; }
        [XmlAttribute]
        public string EventID { get; set; }
        [XmlAttribute]
        public int EventNumber { get; set; }
        [XmlAttribute]
        public int Min { get; set; }
        [XmlAttribute]
        public string Period { get; set; }
        [XmlAttribute]
        public string PlayerRef { get; set; }
        [XmlAttribute]
        public string Reason { get; set; }
        [XmlAttribute]
        public int Sec { get; set; }
        [XmlAttribute]
        public int Time { get; set; }

        private DateTime _TimeStamp { get; set; }
        [XmlAttribute]
        public string TimeStamp
        {
            get { return _TimeStamp.ToString("yyyyMMddTHHmmss+ffff"); }
            set { _TimeStamp = DateTime.ParseExact(value, "yyyyMMddTHHmmss+ffff", CultureInfo.InvariantCulture); }
        }
    }

}

Upvotes: 0

Related Questions