2012-11-30 10 views
5

XMLを解析するためにXmlDocumentを使用するコードを書き直しています。代わりにXmlReaderを使用して、パフォーマンスが向上するかどうかを確認します。 XMLの構造は次のようになります。XmlReaderクラスを使用して同じ名前の要素で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> 

基本的に、私はすべての<item>の要素を反復処理する必要があります。私が言ったように、古いコードは次のように動作します。

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

これは正常に動作しますが、私はしたXmlReaderを使用すると、より高速になると思います。だから私はこれを書いている:

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

しかし、このコードは、最初の<item>の要素を読み込みます。 ReadOuterXml()はループを解除しています。誰かがこれを回避する方法を知っていますか?または、このタイプの解析はXmlReaderでは不可能ですか?私は、だから私は、LINQを使用することはできません。この使用して.NETバージョン2 :(を行うために持ってきた

+1

最初の要素の後どうなりますか?何のデバッグをしましたか?元のコードは実際には遅すぎますか? (もっと速いものを作るのであれば、もっと難しいコードを書いてはいけません...) –

+0

これは応答ではありませんが... xsd2codeを使いましたか? xmlをクラスにパースするのに非常に便利です –

+0

これの戻り値は何ですか?新しいStringReader(xml).ReadToEnd() – laszlokiss88

答えて

1

次は動作するようです: - 。

 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

ちょうどLinqPadでコードをテストしただけでなく作品

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

に出力:。。。

1 one 
2 two 
3 three 
4 four 

たぶんあなたのXMLに問題がある

+0

あなたは.NET 2.0ライブラリを使用していると確信していますか? –

+0

こんにちはオレグ、私はちょうど私の質問を更新しました。私はxml要素を抽出する必要があることを言及することを忘れていました。 –

0

あなたはLINQを使用することができます場合は、ここでは別の方法は次のとおりです。

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

こんにちはジャスティン、応答のおかげで、私は私の質問で言ったように私は.NETのバージョン2を使用してこれを行う必要があります:(だから私はLINQを使用することはできません。 –

関連する問題