ファイル全体をメモリ内の XDocument インスタンスにロードせずに、ルート要素のすぐ下に xs:sequence を含む大きな XML ファイルでストリーミング読み取りを実行するにはどうすればよいでしょうか?
6 に答える
SAXスタイルの要素パーサーとXmlReader.Createで作成されたXmlTextReaderクラスを使用するのは良い考えです。これがCodeGuruからのわずかに変更されたコード例です:
void ParseURL(string strUrl)
{
try
{
using (var reader = XmlReader.Create(strUrl))
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
var attributes = new Hashtable();
var strURI = reader.NamespaceURI;
var strName = reader.Name;
if (reader.HasAttributes)
{
for (int i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToAttribute(i);
attributes.Add(reader.Name,reader.Value);
}
}
StartElement(strURI,strName,strName,attributes);
break;
//
//you can handle other cases here
//
//case XmlNodeType.EndElement:
// Todo
//case XmlNodeType.Text:
// Todo
default:
break;
}
}
}
catch (XmlException e)
{
Console.WriteLine("error occured: " + e.Message);
}
}
}
}
サインアップしたばかりなのでコメントを追加できませんが、Hirvox によって投稿され、現在回答として選択されているコード サンプルにはバグがあります。new
静的Create
メソッドを使用する場合は、ステートメントを含めないでください。
現時点の:
using (var reader = new XmlReader.Create(strUrl))
修理済み:
using (var reader = XmlReader.Create(strUrl))
そのコードサンプルは、XmlReaderスタイルのコードをSAXスタイルのコードに変換しようとします-コードを最初から作成する場合は、意図したとおりにXmlReaderを使用します-プッシュではなくプルします。
オブジェクト モデル (つまり、XElement\XDocument) を使用して XML をクエリする場合、それは不可能だと思います。明らかに、十分なデータを読み取らずに XML オブジェクト ツリーを構築することはできません。ただし、 XmlReaderクラスを使用できます。
XmlReader クラスは、ストリームまたはファイルから XML データを読み取ります。XML データへの非キャッシュ、前方専用、読み取り専用アクセスを提供します。
ここにハウツーがあります: http://support.microsoft.com/kb/301228/en-us XmlTextReader を使用するのではなく、代わりに XmlReader.Create と組み合わせて XmlReader を使用する必要があることを覚えておいてください。
「xs:sequence」について言及されていることに混乱しています。これは XML スキーマ要素です。
大きな XML スキーマ ファイルを開こうとしていますか? そのスキーマに基づく大きな XML ファイルを開いていますか? それとも、大きな XML ファイルを開いて同時に検証しようとしていますか?
これらの状況のいずれでも、標準の XmlReader (または XmlValidatingReader) を使用して問題が発生することはありません。
XMLReader による XML の読み取り: http://msdn.microsoft.com/en-us/library/9d83k261(VS.80).aspx