1

Below is a sample of the type of XML file I am trying to handle. If I have only one part along with an accompanying number/character I can process the data extraction without the necessity of the 'if (!reader.EOF)' control structure. However when I try to include this structure so that I can loop back to checking for another part, number, and character group, it deadlocks.

Any advice as to how to do this properly? This was the most efficient idea that popped into my head. I am new to reading data from XMLs.

Sample Xml:

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <part>100B</part>
  <number>45</number>
  <character>a</character>

  <part>100C</part>
  <number>55</number>
  <character>b</character>
</note>

Code:

String part = "part";
String number = "number";
String character = "character";
String appendString = "";
StringBuilder sb = new StringBuilder();

try
{
    XmlTextReader reader = new XmlTextReader("myPath");
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element: // The node is an element.

                myLabel:
                if (reader.Name == part)
                {
                    part = reader.ReadInnerXml();
                }
                if (reader.Name == number)
                {
                    number = reader.ReadInnerXml();
                    number = double.Parse(number).ToString("F2"); //format num
                }
                if (reader.Name == character)
                {
                    character = reader.ReadInnerXml();
                }

                //new string
                appendString = ("Part: " + part + "\nNumber: " + number +
 "\nCharacter: " + character + "\n");

                //concatenate
                sb.AppendLine(appendString);

                if (reader.EOF != true)
                {
                    Debug.Log("!eof");
                    part = "part";
                    number = "number";
                    character = "character";
                    goto myLabel;
                }

                //print fully concatenated result
                sb.ToString();

                //reset string builder
                sb.Length = 0;

                break;
        }
    }
}
catch (XmlException e)
{
    // Write error.
    Debug.Log(e.Message);
}
catch (FileNotFoundException e)
{
    // Write error.
    Debug.Log(e);
}
catch(ArgumentException e)
{
    // Write error.
    Debug.Log(e);
}
10
  • 2
    Any reason you want to use this approach rather than loading it into an XDocument for example? XmlReader is a very low-level approach. It's helpful if your XML won't fit into memory, but otherwise I'd generally use a higher level abstraction. Commented Oct 4, 2017 at 14:17
  • @JonSkeet Just looked up XDocuments and it appears they represent XML documents. Unsure of how this is better. I only want to parse through the data as presented. Do XDocs provide a more efficient way to do what I am trying to do? I am also not opposed to re-configuring the primitive format I am using. As I said I am new to XMLs. As such, this was the first* (or one of the first) formats google turned up for me. Commented Oct 4, 2017 at 14:24
  • 2
    They provide a much easier way of doing what you're trying to do. It's better because your code would be simpler. XmlReader is likely to be more computationally efficient, but I'd personally err on the side of simple code until you have concrete performance goals. Commented Oct 4, 2017 at 14:38
  • @JonSkeet Thank you for the advice. For right now, Alexanders example is exactly what I was looking for. Commented Oct 4, 2017 at 14:50
  • @JonSkeet Please see op! I figured I would update this thread rather then make a new post. If that is more appropriate please notify. Commented Oct 17, 2017 at 21:14

2 Answers 2

1

XmlReader class has many useful methods. Use it.

See this:

var sb = new StringBuilder();

using (var reader = XmlReader.Create("test.xml"))
{
    while (reader.ReadToFollowing("part"))
    {
        var part = reader.ReadElementContentAsString();
        sb.Append("Part: ").AppendLine(part);

        reader.ReadToFollowing("number");
        var number = reader.ReadElementContentAsDouble();
        sb.Append("Number: ").Append(number).AppendLine();

        reader.ReadToFollowing("character");
        var character = reader.ReadElementContentAsString();
        sb.Append("Character: ").AppendLine(character);
    }
}

Console.WriteLine(sb);
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you kind sir! Perfection.
Please see op! I figured I would update this thread rather then make a new post. If that is more appropriate please notify.
@jtth - Ask a new question. And this return to its original state.
0

Alexander's answer is fine, I just want to add sample using XDocument, according comments of Jon Skeet:

var sb = new StringBuilder();
var note = XDocument.Load("test.xml").Root.Descendants();            
foreach (var el in note)
{                
    sb.Append(el.Name).Append(": ").AppendLine(el.Value);               
}
Console.WriteLine(sb);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.