0

I have an xml structured like this:

Header
  \-Timeseries (1-N)
        \- Period (1-N)
              \- Interval (1-N)

This is an approximate example:

<Header>
<Element />
    <Timeseries>
       <Element />
       <Period>
           <Element />
           <Interval>
               <Element />
           </Interval>
       </Period>
    </Timeseries>
</Header>

I'm hoping to read the header elements until I hit Timeseries, then Timeseries elements until I hit Period, then Period until I hit Interval, and Interval until I hit the end of the Interval. When I'm finished with a Period, I'm writing all Intervals.

This particular document has 614 Timeseries with 1 Period per each Timeseries.

I'm parsing it with:

while (!xmlReader.EOF)
{
    if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Header")
    {
        while (xmlReader.Name != "Timeseries" && xmlReader.Read())
        {
            // read
        }
    }
    else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Timeseries")
    {
        while (xmlReader.Name != "Period" && xmlReader.Read())
        {
            // read
        }           
    }
    else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Period")
    {
        while (xmlReader.Name != "Interval" && xmlReader.Read())
        {
            // read
        }
    }
    else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Interval")
    {
        while (xmlReader.NodeType != XmlNodeType.EndElement && xmlReader.Read())
        {
            // read
        }
    }
    else if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "Period")
    {
        // write intervals
    }
    else
    {
        xmlReader.Read();
    }
}

It appears that only 166/614 Periods are read. Therefore I must be gobbling up some xml, but am having trouble spotting the error.

Dumping the read shows that Timeseries 1-166 are correctly parsed, but somehow the parsing stops after that.

ipavlic
  • 4,906
  • 10
  • 40
  • 77

4 Answers4

1

Not sure it helps at all, but if speed is an issue, perhaps this would be marginally faster?

while (!xmlReader.EOF)
{
    switch(xmlReader.NodeType)
    {
        case XmlNodeType.Element:
            switch(xmlReader.Name)
            {
                case "Header":
                    while (xmlReader.Name != "Timeseries" && xmlReader.Read()) // advance to next node
                    {
                        // read
                    }
                    break;
                case "Timeseries":
                    while (xmlReader.Name != "Period" && xmlReader.Read()) // advance to next node
                    {
                        // read
                    }  
                    break;
                case "Period":
                    while (xmlReader.Name != "Interval" && xmlReader.Read()) // advance to next node
                    {
                        // read
                    }
                    break;
                case "Interval":
                    while (xmlReader.NodeType != XmlNodeType.EndElement && xmlReader.Read()) // advance to next node
                    {
                        // read
                    }
                    break;
            }
            break;

        case XmlNodeType.EndElement:
            if(xmlReader.Name == "Period")
            {
                // write intervals
            }
            break;

        default:
            xmlReader.Read(); // advance to next node
            break;
    }
}

In theory this does a few less comparisons, but it could be an irrelevant difference.

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
  • case would be converted to if-else for ~ N < 6. Element/EndElement might help a bit. – ipavlic Jul 19 '12 at 11:25
  • Yeah, I know switch compiles the same as an if-else, but I was wondering if eliminating the two-part conditional on each else-if would help at all. I suppose if I actually remembered how to compute cyclomatic complexity I wouldn't be wondering... – Tieson T. Jul 20 '12 at 03:20
0

That's because it will never get to the "else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Timeseries")" or the second "else if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "Period")" parts of the code since those conditions are catched by earlier ifs.

Peer
  • 36
  • 5
0

You have a type here? If statement is "Timeseries", but while statement is "Period"

else if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Timeseries")
    {
        while (xmlReader.Name != "Period" && xmlReader.Read())
        {
            // read
        }           
    }

You have another block below doing the same thing.

Valamas
  • 24,169
  • 25
  • 107
  • 177
0

Apparently I counted the total timeseries wrong in my test. The original document has 166 Timeseries as well.

ipavlic
  • 4,906
  • 10
  • 40
  • 77