2012-11-30 5 views
5

Ich schreibe Code um, der ein XmlDocument zum Parsen von XML verwendet. Ich möchte stattdessen einen XmlReader verwenden, um zu sehen, ob ich einige Leistungsverbesserungen erzielen kann. Die Struktur des XML sieht wie folgt aus:Verwenden der XmlReader-Klasse zum Parsen von XML mit gleichnamigen Elementen

<items> 
    <item id="1" desc="one"> 
     <itemBody date="2012-11-12" /> 
    </item> 
    <item id="2" desc="two"> 
     <itemBody date="2012-11-13" /> 
    </item> 
    <item id="3" desc="three"> 
     <itemBody date="2012-11-14" /> 
    </item> 
    <item id="4" desc="four"> 
     <itemBody date="2012-11-15" /> 
    </item> 
</items> 

Grundsätzlich muss ich durch alle <item> Elemente iterieren. Wie ich schon sagte, arbeitet der alte Code wie folgt aus:

XmlDocument document = new XmlDocument(); 

// load XML into XmlDocument 
document.LoadXml(xml); 

// use xpath to split into individual item 
string xPath = @"items/item"; 
XmlNodeList nodeList = document.SelectNodes(xPath); 

// loop through each item 
for (int nodeIndex = 0; nodeIndex < nodeList.Count; nodeIndex++) 
{ 
    // do something with the XmlNode 
    nodeList[nodeIndex]; 
} 

Dies funktioniert gut, aber ich denke, ein XmlReader schneller wäre. Also habe ich dieses geschrieben:

XmlReader xmlReader = XmlReader.Create(new StringReader(xml)); 

while (xmlReader.Read()) 
{      
    if (xmlReader.Name.Equals("item") && (xmlReader.NodeType == XmlNodeType.Element)) 
    { 
     string id = xmlReader.GetAttribute("id");     
     string desc = xmlReader.GetAttribute("desc"); 
     string elementXml = xmlReader.ReadOuterXml(); 
    } 
} 

jedoch dieser Code nur liest das erste <item> Element. Die ReadOuterXml() bricht die Schleife. Weiß jemand, wie man das schafft? Oder ist diese Art des Parsens mit einem XmlReader nicht möglich? Ich habe mit dieser mit .NET Version 2 :(So tun, ich nicht LINQ verwenden können

+1

Was passiert nach dem ersten Element? Welches Debugging hast du gemacht? Ist dein Originalcode * eigentlich * zu langsam? (Schreiben Sie keinen schwierigeren Code, nur um potentiell * Dinge schneller zu machen, wenn sie bereits schnell genug sind ...) –

+0

das ist keine Antwort, aber ... benutzen Sie xsd2code? Ist sehr nützlich, um XML nach Klassen zu analysieren –

+0

Was ist der Rückgabewert davon? new StringReader (xml) .ReadToEnd() – laszlokiss88

Antwort

1

Die folgende scheint zu funktionieren: -.

 StringBuilder xml = new StringBuilder(); 

     xml.Append("<items>"); 
     xml.Append("<item id=\"1\" desc=\"one\">"); 
     xml.Append("<itembody id=\"10\"/>"); 
     xml.Append("</item>"); 
     xml.Append("<item id=\"2\" desc=\"two\">"); 
     xml.Append("<itembody id=\"20\"/>"); 
     xml.Append("</item>"); 
     xml.Append("<item id=\"3\" desc=\"three\">"); 
     xml.Append("<itembody id=\"30\"/>"); 
     xml.Append("</item>"); 
     xml.Append("</items>"); 

     using (XmlTextReader tr = new XmlTextReader(new StringReader(xml.ToString()))) 
     { 
      bool canRead = tr.Read(); 
      while (canRead) 
      { 
       if ((tr.Name == "item") && tr.IsStartElement()) 
       { 
        Console.WriteLine(tr.GetAttribute("id")); 
        Console.WriteLine(tr.GetAttribute("desc")); 
        string outerxml = tr.ReadOuterXml(); 
        Console.WriteLine(outerxml); 

        canRead = (outerxml != string.Empty); 
       } 
       else 
       { 
        canRead = tr.Read(); 
       } 
      } 
     } 
4

gerade getestet Code in LinqPad gut funktioniert

var xml = @"<items> 
    <item id='1' desc='one' /> 
    <item id='2' desc='two' /> 
    <item id='3' desc='three' /> 
    <item id='4' desc='four' /> 
</items>"; 
XmlReader xmlReader = XmlReader.Create(new StringReader(xml)); 

while (xmlReader.Read()) 
{ 
    if (xmlReader.Name.Equals("item") && (xmlReader.NodeType == XmlNodeType.Element)) 
    { 
     string id = xmlReader.GetAttribute("id");    
     string desc = xmlReader.GetAttribute("desc"); 
     Console.WriteLine("{0} {1}", id, desc); 
    } 
} 

Ausgang:...

1 one 
2 two 
3 three 
4 four 

Vielleicht gibt es etwas falsch mit Ihrem XML

+0

Und Sie sind sicher, dass Sie die .NET 2.0-Bibliothek verwenden? –

+0

Hallo Oleg, ich habe gerade meine Frage aktualisiert. Ich habe vergessen zu erwähnen, dass ich das XML-Element extrahieren muss. –

0

Wenn Sie Linq verwenden können, ist hier eine alternative Art und Weise:

class Program 
{ 
    static void Main(string[] args) 
    { 

     const string xml = @"<items> 
          <item id='1' desc='one'> 
          <itemBody date='2012-11-12' /> 
          </item> 
          <item id='2' desc='two'> 
          <itemBody date='2012-11-13' /> 
          </item> 
          <item id='3' desc='three'> 
          <itemBody date='2012-11-14' /> 
          </item> 
          <item id='4' desc='four'> 
          <itemBody date='2012-11-15' /> 
          </item> 
         </items>"; 

     var xmlReader = XmlReader.Create(new StringReader(xml)); 

     XElement element = XElement.Load(xmlReader, LoadOptions.SetBaseUri); 

     IEnumerable<XElement> items = element.DescendantsAndSelf("item"); 

     foreach (var xElement in items) 
     { 
      string id = GetAttributeValue("id", xElement); 
      string desc = GetAttributeValue("desc", xElement); 
      string itemBody = GetElementValue("itemBody", "date", xElement); 

      Console.WriteLine("id = {0}, desc = {1}, date = {2}", id, desc, itemBody); 
     } 

     Console.ReadLine(); 
    } 

    private static string GetElementValue(string elementName, string attributeName, XElement element) 
    { 
     XElement xElement = element.Element(elementName); 

     string value = string.Empty; 

     if (xElement != null) 
     { 
      XAttribute xAttribute = xElement.Attribute(attributeName); 

      if (xAttribute != null) 
      { 
       value = xAttribute.Value; 
      } 
     } 

     return value; 
    } 

    private static string GetAttributeValue(string attributeName, XElement element) 
    { 
     XAttribute xAttribute = element.Attribute(attributeName); 

     string value = string.Empty; 
     if (xAttribute != null) 
     { 
      value = xAttribute.Value; 
     } 

     return value; 
    } 
} 
+0

Hallo Justin, danke für die Antwort, aber wie ich in meiner Frage gesagt habe, muss ich dies mit .NET Version 2 tun :(Also kann ich LINQ nicht verwenden. –

Verwandte Themen