2009-10-14 2 views
13
私は大きなファイルの大きな数を解析しています

から、私のボトルネックをプロファイリングした後XMLNodeのを構築する方法である:私はこのようなノードを抽出する可能性があるためたXmlReader

XmlDocument doc = new XmlDocument(); 
doc.Load(filename); 

このアプローチは非常に便利だった:

XmlNodeList nodeList = doc.SelectNodes("myXPath"); 

私がしたXmlReaderに切り替えるのですが、私は要素を見つけたとき、私は私がしたXmlReaderとあまり慣れていないとして、それからのXmlNodeを構築する方法に関して立ち往生午前抽出する必要があります。

XmlReader xmlReader = XmlReader.Create(fileName); 

while (xmlReader.Read()) 
{ 
    //keep reading until we see my element 
    if (xmlReader.Name.Equals("myElementName") && (xmlReader.NodeType == XmlNodeType.Element)) 
    { 
     // How do I get the Xml element from the reader here? 
    } 
} 

List<XmlNode>オブジェクトを構築したいと考えています。私はです。.NET 2.0です。

答えて

6

タイプはパブリックコンストラクタを持たないため、独自に作成することはできません。あなたがそれらを作成するために使用することができますXmlDocumentを持っている必要があります:

XmlDocument doc = new XmlDocument(); 
while (xmlReader.Read()) 
{ 
    //keep reading until we see my element 
    if (xmlReader.Name.Equals("myElementName") && (xmlReader.NodeType == XmlNodeType.Element)) 
    { 
     // How do I get the Xml element from the reader here? 
     XmlNode myNode = doc.CreateNode(XmlNodeType.Element, xmlReader.Name, ""); 
     nodeList.Add(myNode); 
    }   
} 
+1

空ノードが作成されているようですか? – JohnIdol

+0

はい、要素に何かを追加しない限り(例えば、何かを 'InnerText'プロパティに代入することによって)それらは空になります。 –

+0

ああ、ちょうど今私はちょうど要素名を渡しているので明らかに見える – JohnIdol

5

XmlReaderXmlDocumentは、処理の非常に明確な方法を持っています。 XmlReaderは、メモリ内に何も保持せず、XmlDocumentのメモリ内に完全なDOMツリーを構築するのではなく、前方のみのアプローチを使用します。パフォーマンスが問題になる場合に役立ちますが、別の方法でアプリケーションを書く必要があります。XmlNodeを使用する代わりに、何も保持せずに「外出先で」処理するだけです。 、あなたは何かをする。これはSAXのアプローチに近いですが、コールバックモデルはありません。

「XmlElementを取得する方法」の答えは、リーダーからの情報に基づいて最初からビルドする必要があります。残念なことに、これはパフォーマンスの向上に繋がりません。少数の明瞭なケースを除いて、XmlReaderに切り替えた後は、DOMアプローチを一切使用しないようにする方がしばしばです。

また、XPath(上記のSelectNodesがあなたのものです)を使用してノードを抽出する方法は、ここでは使用できません.XPathにはDOMツリーが必要です。このアプローチをフィルタリングのアプローチと考えてください。XmlReaderにフィルタを追加し、特定のノードをスキップするように、または特定のノードまで読み取るように指示できます。これは非常に高速ですが、考え方が異なります。

4

このアプローチにはXmlDocument.ReadNodeを使用してください。 usingステートメントにXmlReaderを入れ、名前の代わりにXmlReader.LocalNameを使用して、名前空間接頭辞を削除します。

1

私はXmlDocumenhtXmlReaderからデータを挿入するために持っていたとき、私は次の回避策を使用しました:

XmlReader rdr = cmd.ExecuteXmlReader(); 

XmlDocument doc = new XmlDocument(); 

// create a container node for our resultset 
XmlElement root = doc.CreateElement("QueryRoot"); 
doc.AppendChild(root); 

StringBuilder xmlBody = new StringBuilder(); 

while(rdr.Read()) 
{ 
    xmlBody.Append(rdr.ReadOuterXml()); 
} 

root.InnerXml = xmlBody.ToString(); 
12

はなぜ、次の操作を実行していませんか?

public static IEnumerable<XmlNode> StreamNodes(
    string path, 
    string[] tagNames) 
{    
    var doc = new XmlDocument();    
    using (XmlReader xr = XmlReader.Create(path)) 
    { 
     xr.MoveToContent(); 
     while (true) { 
      if (xr.NodeType == XmlNodeType.Element && 
       tagNames.Contains(xr.Name)) 
      { 
       var node = doc.ReadNode(xr); 
       yield return node; 
      } 
      else 
      { 
       if (!xr.Read()) 
       { 
        break; 
       } 
      } 
     } 
     xr.Close(); 
    }       
} 
// Used like this: 
foreach (var el in StreamNodes("orders.xml", new string[]{"order"})) 
{ 
    .... 
} 

ノードは、さらなる処理のために別の文書にインポートすることができます。

XmlDocument doc = new XmlDocument(); 
XmlNode node = doc.ReadNode(reader); 
+0

すでに答えました。 http://stackoverflow.com/questions/1566192/how-to-build-xmlnodes-from-xmlreader/1566333#1566333を参照してください。 –

+0

これは正しい答えです。もう1つは空ノードです。 –

0

は、ここに私のアプローチです。