here is the code

using System.Text; using System.Xml; using System.Xml.Linq; using System.IO; namespace TestApp_Dipl { class Program { static int iter; static void Main(string[] args) { Program ThisClass = new Program(); Console.WriteLine("Main"); XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load("File.xml"); XmlNodeList _fnames = XmlDoc.GetElementsByTagName("CD"); Console.WriteLine(_fnames.Count.ToString()); ThisClass.GetNodes(_fnames); Console.ReadKey(); } void GetNodes(XmlNodeList NodeListVar) { int i = 1; foreach (XmlNode el in NodeListVar) { if (el.HasChildNodes) { Console.WriteLine(i++ + ". " + el.Name); GetNodes(el.ChildNodes); } else { Console.WriteLine("-> " + el.InnerText); } } } } } 

Xml file.xml

 <?xml version="1.0" encoding="UTF-8"?> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Hide your heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS Records</COMPANY> <PRICE>9.90</PRICE> <YEAR>1988</YEAR> </CD> </CATALOG> 

I would like to get in the console like this:

 CATALOG 1.CD TITLE Empire Burlesque ARTIST Bob Dylan COUNTRY USA COMPANY Columbia PRICE 10.90 YEAR 1985 2.CD TITLE Hide your heart ARTIST Bonnie Tyler COUNTRY UK COMPANY CBS Records PRICE 9.90 YEAR 1988 
  • Do you need recursion? On the microsoft site there is an example of how to output a string as in [2], and in the simplest case, replace or regexp + replace all tags can be removed. - nick_n_a

2 answers 2

If you do not require functionality specific to the XmlDocument class, it is easier to use the XDocument from the System.Xml.Linq namespace. This will provide a more compact code.

For output to the console in the form that you indicated there are three ways.

1. Recursively traversing an XML tree

It is implemented quite simply:

 static void Main(string[] args) { XElement doc = XElement.Load(@"H:\test.xml"); PrintElementV1(doc); Console.ReadKey(); } static void PrintElementV1(XElement elem) { if (elem.Elements().Count() > 0) { Console.WriteLine(elem.Name); foreach (XElement e in elem.Elements()) { PrintElementV1(e); } } else { Console.WriteLine("{0}: {1}", elem.Name, elem.Value); } } 

But to insert into this water the electoral numbering of specific elements without “crutches” will not work. The “crutch” for numbering may look like this:

 static void PrintElementV1(XElement elem, int num) { if (elem.Elements().Count() > 0) { Console.WriteLine("{0}. {1}", num, elem.Name); int i = 1; foreach (XElement e in elem.Elements()) { PrintElementV1(e, i++); } } else { Console.WriteLine("{0}: {1}", elem.Name, elem.Value); } } 

In this case, all elements except those that do not contain other elements will be numbered.

2. Fixed traversal of the XML tree

From the point of view of the tree, the recursion is preserved, such is the structure of the tree, but if this structure is fixed and known , then you can do without recursive calling methods and use a chain of calls in a loop. I will show by example:

 static void Main(string[] args) { XElement doc = XElement.Load(@"H:\test.xml"); Console.WriteLine(doc.Name); PrintCDList(doc); Console.ReadKey(); } static void PrintCDList(XElement elem) { int i = 1; foreach (XElement e in elem.Elements()) { Console.WriteLine("{0}. {1}", i++, e.Name); PrintContent(e); } } static void PrintContent(XElement elem) { foreach (XElement e in elem.Elements()) { Console.WriteLine("{0}: {1}", e.Name, e.Value); } } 

As you can see, there is no recursion, but if the XML structure differs from the one in the code, “everything will turn into a pumpkin” and will give incorrect results.

3. Manual parsing

You can do all the work with your hands by getting the XML source text as text. To do this, you can use any way you know how to get text from a file.

Next, we apply all sorts of regular expressions or other methods of transforming a string to the source XML string to obtain a string or an array of strings of the desired type and print the result.

I will not give the code of this method, because there are a lot of options for such a solution, and there are many other views on how to do it correctly. In addition, I strongly doubt that this option will be much more productive than the previous two, rather the opposite.

Choose which option suits you best =)

PS: If it is important to use XmlDocument , write in the comments, I will add the corresponding example.

  • And how can you parse a large xml file into tags, attributes? - Alexander
  • one
    @Chelovek can be. There is a XNode class, it, like XmlNode represents any valid element, there is an XAtribute - here it’s understandable, etc. Look at the description of the namespace System.Xml.Linq , there are a lot of useful things there. If you do not understand it yourself - write a separate question, but in general there is just everything and there are examples - rdorn

You can try something like this:

 int i = 1; var xElems = XDocument.Load(file, LoadOptions.SetLineInfo).Descendants("CD"); foreach (var xElem in xElems) { Console.WriteLine($"{i++} - {xElem.Name}"); foreach (var xElem2 in xElem.Descendants()) { Console.WriteLine($"{xElem2.Name} - {xElem2.Value}"); } }