C#x具有多个根的文档负载
我有一个没有根的XML文件。我不能改变这个。我正试图解析它,但C#x具有多个根的文档负载,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我有一个没有根的XML文件。我不能改变这个。我正试图解析它,但XDocument.Load无法解析。我已尝试设置ConformanceLevel.Fragment,但仍引发异常。有人能解决这个问题吗 我试过使用XmlReader,但是事情搞砸了,无法正常工作XDocument.Load工作得很好,但是如果我有一个具有多个根的文件,它就不工作了。XmlReader本身就支持读取xml片段,即 var settings = new XmlReaderSettings { ConformanceLev
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
快速而肮脏的方法是在调用XDocument.Parse
之前将节点包装在一个虚拟根下。比如:
var fragments = File.ReadAllText("fragment.xml");
var myRootedXml = "<root>" + fragments + "</root>";
var doc = XDocument.Parse(myRootedXml);
MultiStream-参见示例
注意:
XDocument
将整个xml加载到内存中。因此,不要将其用于大文件-而是使用XmlReader
进行迭代,并通过XNode将脆位作为XElement
加载。ReadFrom(…)
XML文档不能有多个根元素。需要一个根元素。你可以做一件事。获取所有片段
元素,并将它们包装到根元素中,然后使用XDocument
对其进行解析
这将是人们所能想到的最好、最简单的方法。如果要使用XmlDocument.Load(),则需要将内容包装在根节点中 或者你可以试试这样的
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
XmlDocument d = new XmlDocument();
d.CreateElement().InnerText = xmlReader.ReadOuterXml();
}
}
.NET framework中唯一可以处理片段的内存树表示是.NET的DOM实现中的
XmlDocumentFragment
,因此您需要创建XmlDocument
和一个片段,例如
XmlDocument doc = new XmlDocument();
XmlDocumentFragment frag = doc.CreateDocumentFragment();
frag.InnerXml = stringWithXml; // for instance
// frag.InnerXml = File.ReadAllText("fragment.xml");
或者是XPathDocument
,您可以使用ConformanceLevel设置为Fragment的XmlReader创建一个:
XPathDocument doc;
using (XmlReader xr =
XmlReader.Create("fragment.xml",
new XmlReaderSettings()
{
ConformanceLevel = ConformanceLevel.Fragment
}))
{
doc = new XPathDocument(xr);
}
// new create XPathNavigator for read out data e.g.
XPathNavigator nav = doc.CreateNavigator();
显然,XPathNavigator是只读的
如果您想使用LINQtoXML,那么我同意您提出的需要创建一个XElement作为包装器的建议。但是,您可以使用XmlReader使用XNode.ReadFrom
,而不是使用包含文件内容的字符串
public static class MyExtensions
{
public static IEnumerable<XNode> ParseFragment(XmlReader xr)
{
xr.MoveToContent();
XNode node;
while (!xr.EOF && (node = XNode.ReadFrom(xr)) != null)
{
yield return node;
}
}
}
这可能比将所有内容读入字符串更有效。
XDocument.Load
不起作用,因为这种文件不是有效的XML文档。您能发布您迄今为止尝试过的代码吗?不同的问题,同样的答案:为什么不能直接使用XElementparse@phillip因为这样会出现以下异常:缺少根元素。使用XDocument.Parse()
可以消除在StringReader
中包装字符串的需要。
public static class MyExtensions
{
public static IEnumerable<XNode> ParseFragment(XmlReader xr)
{
xr.MoveToContent();
XNode node;
while (!xr.EOF && (node = XNode.ReadFrom(xr)) != null)
{
yield return node;
}
}
}
XElement root = new XElement("root",
MyExtensions.ParseFragment(XmlReader.Create(
"fragment.xml",
new XmlReaderSettings() {
ConformanceLevel = ConformanceLevel.Fragment })));