Yoav
Yoav

Reputation: 305

Repeated value read from XmlNode

I am reading repeating xml nodes and populating the values into objects. I can see in debug mode that the node is changing each loop, but the objects are still populated with the value from the first node.

Stackoverflow wants me to add more text so here goes:
The call to populate noteNodes works fine, on inspection I can see all three nodes populated as expected.
In the first foreach clause, on inspection, I can see that the code is using the correct node each time.
It is only when it is doing the assignments to Step and Octave where it is reverting to the value of the first note.

class Program
    {
        class Note
        {
            private int sequence;
            private string step;
            private string octave;

            public string Step { get => step; set => step = value; }
            public int Sequence { get => sequence; set => sequence = value; }
            public string Octave { get => octave; set => octave = value; }

            public override string ToString()
            {
                return $"[{sequence}] {step} {octave}";
            }
        }

        static void Main(string[] args)
        {
            XmlDocument guitarTab = new XmlDocument();
            List<Note> notes = new List<Note>();

            try
            {
                guitarTab.Load(AppDomain.CurrentDomain.BaseDirectory + "\\Tab-example.xml");
                XmlNodeList noteNodes = guitarTab.SelectNodes("//score-partwise/part/measure/note");
                int sequence = 0;

                foreach (XmlNode node in noteNodes)
                {
                    Note note = new Note();
                    note.Sequence = sequence++;
                    note.Step = node.SelectSingleNode("//pitch/step").InnerText;
                    note.Octave = node.SelectSingleNode("//pitch/octave").InnerText;
                    notes.Add(note);
                }

                foreach (Note note in notes)
                {
                    Console.WriteLine(note.ToString());
                }

                Console.ReadKey();
            }

            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

The file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<score-partwise>
    <part id="P1">
        <measure number="1">
            <note>
                <pitch>
                    <step>E</step>
                    <octave>3</octave>
                </pitch>
            </note>
            <note>
                <pitch>
                    <step>D</step>
                    <octave>5</octave>
                </pitch>
            </note>
            <note>
                <pitch>
                    <step>B</step>
                    <octave>7</octave>
                </pitch>
            </note>
        </measure>        
    </part>
</score-partwise>

The result:

[0] E 3
[1] E 3
[2] E 3

Upvotes: 0

Views: 37

Answers (1)

Klaus G&#252;tter
Klaus G&#252;tter

Reputation: 11997

The //pitch/step will select the first <step> element in the document. Remove the // from it to make it nagivate relative to node:

note.Step = node.SelectSingleNode("pitch/step").InnerText;
note.Octave = node.SelectSingleNode("pitch/octave").InnerText;

Upvotes: 1

Related Questions