Frage

I am creating XML index files to be read in a later step. I have variable length arrays, and I am writing them to one file.

There is a problem, I think its inside the reader code. For some reason the TimeStamp and Long elements are read into arrays properly, but the Lat and VideoFile elements are skipped. For some reason, thier reader.nodetype is never returned. The only way the read() method picks them up is in a TEXT nodetype, and then it only shows the innerxml value, which is useless to me.

The code below should be fully runnable once you save an example of the XML file.

Once again, thank-you stack users.

Creation

    using System.Xml;        
    XmlTextWriter xmlwriter = new XmlTextWriter(file, null);
    xmlwriter.Formatting = Formatting.Indented;
    //xmlwriter.Indentation = 4;
    xmlwriter.WriteStartDocument();
    xmlwriter.WriteStartElement("Index");

    for (int i = 0; i < malLat.Count; i++)
    {
        xmlwriter.WriteStartElement("Marker");

        xmlwriter.WriteStartElement("TimeStamp");
        xmlwriter.WriteString(malTimes[i].ToString());
        xmlwriter.WriteEndElement();

        xmlwriter.WriteStartElement("Lat");
        xmlwriter.WriteString(malLat[i].ToString());
        xmlwriter.WriteEndElement();

        xmlwriter.WriteStartElement("Long");
        xmlwriter.WriteString(malLong[i].ToString());
        xmlwriter.WriteEndElement();

        xmlwriter.WriteStartElement("VideoFile");
        xmlwriter.WriteString(malVideoTitle[i].ToString());
        xmlwriter.WriteEndElement();

        xmlwriter.WriteEndElement();
    }
    xmlwriter.WriteEndElement();
    xmlwriter.WriteEndDocument();
    xmlwriter.Close();

Reading

using System.Xml;  
XmlTextReader lxmlReader = new XmlTextReader(mstrIndexFile + ".xml");
lxmlReader.WhitespaceHandling = WhitespaceHandling.None;

while (lxmlReader.Read())
{
    if (lxmlReader.NodeType == XmlNodeType.Element)
    {
        if (lxmlReader.Name == "TimeStamp")
        {
            malTimes.Add(lxmlReader.ReadInnerXml().ToString());
        }
        else if (lxmlReader.Name == "Lat")
        {
            malLat.Add(lxmlReader.ReadInnerXml().ToString());
        }
        else if (lxmlReader.Name == "Long")
        {
            malLong.Add(lxmlReader.ReadInnerXml().ToString());
        }
        else if (lxmlReader.Name == "VideoFile")
        {
            malVideoTitle.Add(lxmlReader.ReadInnerXml().ToString());
        }
    }
}

lxmlReader.Close();

XML Doc Sample

    <Index>
      <Marker>
        <TimeStamp>2011-7-17 23:18:39</TimeStamp>
        <Lat>-121.261953323166</Lat>
        <Long>43.0594755392741</Long>
        <VideoFile>C:\Users\kpenner\Desktop\Video Dev\1_1.wmv</VideoFile>
      </Marker>
      <Marker>
        <TimeStamp>2011-7-17 23:18:40</TimeStamp>
        <Lat>-122.260755</Lat>
        <Long>46.05878</Long>
        <VideoFile>C:\Users\kpenner\Desktop\Video Dev\1_1.wmv</VideoFile>
      </Marker>
    </Index>
War es hilfreich?

Lösung

The issue the XmlTextReader is a forward-only reader. When you perform the ReadInnerXml against the reader on a leaf node, it moves to the next element (see http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readinnerxml.aspx). So in this case, when you hit TimeStamp and perform a ReadInnerXml, the reader then moves the to the Lat Element type because these 4 elements are leaf nodes. Then you read again in your while loop which moves the reader to the Text element of Lat. Since you are only checking for Element types, it works itself out until you hit Long which then breaks VideoFile for the same reasons.

Here is a link to another SO question with an answer which may help with your solution: XMLTextReader not reading an element content.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top