2012-11-30 11 views
5

Przepisuję kod, który używa XmlDocument do parsowania niektórych XML. Chcę zamiast tego użyć XmlReader, aby sprawdzić, czy mogę uzyskać poprawę wydajności. Struktura XML wygląda następująco:Używanie klasy XmlReader do parsowania XML z elementami o tej samej nazwie

<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> 

Zasadniczo muszę iterację wszystkich <item> elementów. Tak jak mówiłem, stary kod działa tak:

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]; 
} 

Działa to dobrze, ale myślę, że przy użyciu XmlReader byłoby szybciej. Więc pisałem tak:

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(); 
    } 
} 

Jednak ten kod odczytuje tylko pierwszy <item> element. ReadOuterXml() przerywa pętlę. Czy ktoś wie, jak sobie z tym poradzić? Czy ten typ analizy nie jest możliwy z XmlReader? Ja mając to zrobić przy użyciu wersji .NET 2 :(Więc nie mogę używać LINQ

+1

Co dzieje się po pierwszym elemencie? Jakie debugowanie zrobiłeś? Czy Twój oryginalny kod * faktycznie * jest zbyt wolny? (Nie pisz trudniejszego kodu po prostu * potencjalnie * przyspieszaj rzeczy, jeśli są już wystarczająco szybkie ...) –

+0

to nie jest odpowiedź, ale ... czy użyłeś xsd2code? Jest bardzo przydatne do parsowania xml do klas –

+0

Jaka jest zwracana wartość tego? new StringReader (xml) .ReadToEnd() – laszlokiss88

Odpowiedz

1

Poniższy wydaje się działać: -.

 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

Wystarczy przetestowany kod w LINQPad działa dobrze

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); 
    } 
} 

wyjściowa:...

1 one 
2 two 
3 three 
4 four 

Może coś jest nie tak z XML

+0

Jesteś pewien, że używasz biblioteki .NET 2.0? –

+0

Witaj, Oleg, właśnie zaktualizowałem moje pytanie. Zapomniałem wspomnieć, że muszę wyodrębnić element xml. –

0

Jeśli można użyć LINQ, tutaj jest alternatywny sposób:

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

Witaj Justin, dziękuję za odpowiedź, ale jak powiedziałem w moim pytaniu, muszę to zrobić używając .NET wersji 2 :(Więc nie mogę używać LINQ. –

Powiązane problemy