我有一个非常大的XML文件(> 100MB),我想只通过Linq到XML查看其中的一些小元素。
我知道有很多方法可以做到这一点,但是我希望将它保存在内存中,以便在整个程序中的不同位置使用,因此,我想要做的就是遍历此文档一次XMLReader
并创建我自己的XDocument
变量,其中只包含我需要查看的元素,但我不确定如何正确执行此操作。
这是我到目前为止所用代码的基础知识:
XDocument parsedXml = new XDocument();
using (var rdr = new XmlTextReader(fileName))
{
rdr.MoveToContent();
rdr.Read();
while (rdr.NodeType == XmlNodeType.Element)
{
switch (rdr.Name)
{
case "Node1":
case "Node2":
case "Node3":
XElement newNode = XElement.Load(rdr.ReadSubtree());
parsedXml.Add(newNode);
rdr.Read();
break;
default:
rdr.Skip();
break;
}
}
rdr.Close();
}
它适用于我添加的第一个元素,但是当我尝试添加任何其他节点时,我收到错误 - This operation would create an incorrectly structured document
。
实现这个目标的最佳方法是什么?
谢谢!
答案 0 :(得分:1)
我想出了这个作为我的解决方案 - 如果有更好的方法,请让我知道/发布您的解决方案,但是,如果没有,我希望这有助于其他人....
XDocument parsedXml = new XDocument();
parsedXml.AddFirst(new XElement("root"));
using (var rdr = new XmlTextReader(fileName))
{
rdr.MoveToContent();
rdr.Read();
while (rdr.NodeType == XmlNodeType.Element)
{
switch (rdr.Name)
{
case "Node1":
case "Node2":
case "Node3":
XElement newNode = XElement.Load(rdr.ReadSubtree());
parsedXml.Root.Add(newNode);
rdr.Read();
break;
default:
rdr.Skip();
break;
}
}
rdr.Close();
}
基本上,创建根节点:
parsedXml.AddFirst(new XElement("root"));
然后专门添加:
parsedXml.Root.Add(newNode);
希望这也有助于其他人!!
答案 1 :(得分:1)
使用Xslt就像:
一样简单XDocument parsedXml = new XDocument();
using (var xr = XmlReader.Create(fileName))
{
using (var xw = parsedXml.CreateWriter())
{
XslCompiledTransform ct = new XslCompiledTransform();
ct.Load(xsltFileName);
ct.Transform(fileName, xw);
}
}
我尝试进行一些快速分析,但我手边没有合适的Xml源代码,因此您可能需要尝试使用真实数据。
虽然您可能的简化示例肯定不需要复杂的转换,但Xslt可以快速胜过真实世界数据所需的switch-case
或if
。
值得注意的另一件事是使用XmlReader.Create()
XmlTextReader()
而不是{{1}}