最も可能性が高い理由は、あなたが文字列に1ギガバイトのXML文書のかなりの部分を読み込むしようとしている、とMaximum string length in .Netをヒットしているということです。
だから、しないでください。が代わりにXmlReader.ReadSubtree()
とXDocument.Load()
を使用してXmlReader
から直接ロード:GetDetails()
で
using (var xr = XmlReader.Create(fileName))
{
while (xr.Read() && success)
{
if (xr.NodeType != XmlNodeType.Element)
continue;
switch (xr.Name)
{
case "A":
{
// ReadSubtree() positions the reader at the EndElement of the element read, so the
// next call to Read() moves to the next node.
using (var subReader = xr.ReadSubtree())
{
var doc = XDocument.Load(subReader);
GetDetails(doc);
}
}
break;
}
}
}
そして操作を行います。
private int GetDetails(XDocument rootDocument)
{
var xnodes = rootDocument.XPathSelectElements("//A/B").ToList();
//Then working on list of nodes
return xnodes.Count;
}
だけでなく、これは、より少ないメモリを使用しますが、それはまた、よりパフォーマンスになります。 ReadOuterXml()
は、一時的なXmlWriter
を使用して、入力ストリーム内のXMLを出力StringWriter
にコピーします(次に2回目の解析を行います)。このバージョンのアルゴリズムは、この余分な作業を完全にスキップします。 large object heapを実行するのに十分な大きさの文字列を作成することも回避され、パフォーマンスの問題がさらに発生する可能性があります。
これはまだあなたが一度に一つの要素<B>
をロードする場所をSAX-likeがあなたのXMLのパースを実装する必要がありますあまりにも多くのメモリを使用している場合。次のようにそれを使用し、その後
public static partial class XmlReaderExtensions
{
public static IEnumerable<XElement> WalkXmlElements(this XmlReader xmlReader, Predicate<Stack<XName>> filter)
{
Stack<XName> names = new Stack<XName>();
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
names.Push(XName.Get(xmlReader.Name, xmlReader.NamespaceURI));
if (filter(names))
{
using (var subReader = xmlReader.ReadSubtree())
{
yield return XElement.Load(subReader);
}
}
}
if ((xmlReader.NodeType == XmlNodeType.Element && xmlReader.IsEmptyElement)
|| xmlReader.NodeType == XmlNodeType.EndElement)
{
names.Pop();
}
}
}
}
:まず、次の拡張方法を紹介するXMLファイルの
using (var xr = XmlReader.Create(fileName))
{
Predicate<Stack<XName>> filter =
(stack) => stack.Peek().LocalName == "B" && stack.Count > 1 && stack.ElementAt(1).LocalName == "A";
foreach (var element in xr.WalkXmlElements(filter))
{
//Then working on the specific node.
}
}
出典
2017-10-08 07:08:19
dbc
どのサイズ我々はここで話しているの? – Flater
読み込まれたxmlのサイズが大きすぎます。イテレータを使ってメモリを節約する 'GetDetails'の結果を得ることができます。 – Fabio
こんにちは@Flater、XMLのサイズはほぼ1 GBです – Aniket