ルートのない XML ファイルがあります。これを変更することはできません。私はそれを解析しようとしていますが、それXDocument.Load
を行いません。を設定しようとしましたConformanceLevel.Fragment
が、それでも例外がスローされます。誰にもこれに対する解決策がありますか?
で試してみましXmlReader
たが、物事がめちゃくちゃで、正しく動作しません。XDocument.Load
うまく機能しますが、複数のルートを持つファイルがある場合は機能しません。
ルートのない XML ファイルがあります。これを変更することはできません。私はそれを解析しようとしていますが、それXDocument.Load
を行いません。を設定しようとしましたConformanceLevel.Fragment
が、それでも例外がスローされます。誰にもこれに対する解決策がありますか?
で試してみましXmlReader
たが、物事がめちゃくちゃで、正しく動作しません。XDocument.Load
うまく機能しますが、複数のルートを持つファイルがある場合は機能しません。
XmlReader
それ自体はxmlフラグメントの読み取りをサポートしています-つまり
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (var reader = XmlReader.Create("fragment.xml", settings))
{
// you can work with reader just fine
}
ただしXDocument.Load
、断片化された xml の読み取りはサポートしていません。
手っ取り早い方法は、 を呼び出す前にノードを 1 つの仮想ルートの下にラップすることですXDocument.Parse
。お気に入り:
var fragments = File.ReadAllText("fragment.xml");
var myRootedXml = "<root>" + fragments + "</root>";
var doc = XDocument.Parse(myRootedXml);
このアプローチは、最初にファイルをメモリに読み込む必要があるため、小さな xml ファイルに限定されます。大きな文字列を連結することは、メモリ内の大きなオブジェクトを移動することを意味します。これは避けるのが最善です。
パフォーマンスが重要な場合は、優れた @Martin-Honnen の回答 ( https://stackoverflow.com/a/18203952/2440262 )で説明されているように、ノードをXDocument
1 つずつ読み込む必要があります。XmlReader
XmlReader
有効な xmlを反復処理するのが当然の API を使用し、パフォーマンスが問題になる場合は、代わりに結合ストリーム アプローチを使用できます。
using (var jointStream = new MultiStream())
using (var openTagStream = new MemoryStream(Encoding.ASCII.GetBytes("<root>"), false))
using (var fileStream =
File.Open(@"fragment.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
using (var closeTagStream = new MemoryStream(Encoding.ASCII.GetBytes("</root>"), false))
{
jointStream.AddStream(openTagStream);
jointStream.AddStream(fileStream);
jointStream.AddStream(closeTagStream);
using (var reader = XmlReader.Create(jointStream))
{
// now you can work with reader as if it is reading valid xml
}
}
マルチストリーム - たとえば、https: //gist.github.com/svejdo1/b9165192d313ed0129a679c927379685 を参照してください
注: XDocument
xml 全体をメモリにロードします。そのため、大きなファイルには使用しないでください。代わりにXmlReader
、反復に使用し、クリスピー ビットのみXElement
を経由してロードします。XNode.ReadFrom(...)
XmlDocument.Load() を使用する場合は、ルート ノードでコンテンツをラップする必要があります。
または、このようなことを試すことができます...
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
XmlDocument d = new XmlDocument();
d.CreateElement().InnerText = xmlReader.ReadOuterXml();
}
}
XML ドキュメントに複数のルート要素を含めることはできません。ルート要素が 1 つ必要です。あなたは一つのことをするかもしれません。すべてのfragment
要素を取得してルート要素にラップし、 で解析しXDocument
ます。
これは、考えられる最善かつ最も簡単なアプローチです。