0

2.5GBのXMLファイルを読み、特定のノード、たとえば「CD」要素と「DVD」要素を削除しようとしています。現在、私は次のようなことをしています。

using (XmlReader reader = XmlReader.Create("file.xml"))
{
    DeleteElements(reader.ReadElements("CD"));
    DeleteElements(reader.ReadElements("DVD")); // reader returns 0 elements
}

注:DeleteElementsこれらの要素をループしてドキュメントから削除するだけですが、この質問の目的ではほとんど重要ではありません。

現在、「DVD」要素が取得されていないことがわかりました。これまでXmlReaderに多くの作業を行ったことがある場合は、ここで問題の原因を理解できると確信しています。リーダーが「CD」ノードのドキュメントを読んだ後、リーダーが「DVD」要素を見つけられないのは、リーダーがドキュメントの最後にあります。

XMLファイルのサイズが大きく、取得しようとしている要素の数を考慮すると、ドキュメント全体をメモリにロードできませんOutOfMemoryException。これは、XDocumentまたはXPathDocumentが適切でないことを意味します。

XmlReaderがドキュメントを読み取るときに「CD」と「DVD」の両方を返すようにする方法はありますか?最初にドキュメントをロードするのはかなり時間がかかるので、これを何度もやりたくありません。何か素晴らしいものが甘いreader.ReadElements("DVD|CD")でしょう。

4

1 に答える 1

2

XmlReaderは、転送専用のxmlパーサーです。ReadElementsメソッドがある場合は、リーダーが最後まで実行され、DVD要素はなくなります。したがって、ファイルに対して2回実行する必要があります。

XmlReaderの基本的な使用法:

using (XmlReader reader = XmlReader.Create("input.xml")) {
  while (reader.Read()) {
    switch (reader.NodeType) {
    case XmlNodeType.Element:
      switch (reader.Name) {
      case "CD":
        // do something with a CD
        break;
      case "DVD":
        // do something with a DVD
        break;
      default:
        // do something with all other elements
        break;
      }
      break;
    }
  }
}

DeleteElementsメソッドで何をしていますか?おそらく、新しい一時ファイル用にXmlWriterを作成してから、削除する要素を除くすべての要素を一時ファイルに書き込み、少なくとも元のファイルを一時ファイルに置き換える必要があります。

このようにして、一部の削除(除外)を含め、すべての要素に対して1つのループがあります。

于 2012-12-21T02:05:18.553 に答える