16

多数の大きなファイルを解析していますが、プロファイリングした後のボトルネックは次のとおりです。

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を使用しています。

どんな助けでも大歓迎です!

4

6 に答える 6

18

なぜ次のことをしないのですか?

XmlDocument doc = new XmlDocument();
XmlNode node = doc.ReadNode(reader);
于 2010-04-15T13:38:48.633 に答える
7

このXmlNode型にはパブリックコンストラクターがないため、自分で作成することはできません。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);
    }        
}
于 2009-10-14T13:30:25.787 に答える
6

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

「XmlElement を取得する方法」に対する答えは、リーダーからの情報に基づいてゼロから作成する必要があるということです。残念ながら、これはパフォーマンスの向上に反します。XmlReader に切り替えたら、いくつかの明確なケースがない限り、DOM アプローチを完全に使用しない方がよい場合がよくあります。

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

于 2009-10-14T13:32:17.203 に答える
4

XmlDocument.ReadNodeこのアプローチに使用します。名前空間プレフィックスを削除するにはXmlReader、using ステートメントを挿入し、Name の代わりに使用します。XmlReader.LocalName

于 2009-10-14T13:46:10.490 に答える
1

これが私のアプローチです:

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"})) 
{
    ....
}

その後、ノードを別のドキュメントにインポートして、さらに処理することができます。

于 2011-05-02T08:30:27.363 に答える
1

から にデータを挿入する必要がある場合は、次の回避策を使用しましXmlReaderXmlDocumenht

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();
于 2009-11-03T17:45:39.530 に答える