while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == itemElementName)
{
XElement item = null;
try
{
item = XElement.ReadFrom(reader) as XElement;
}
catch (XmlException ex)
{
//log line number and stuff from XmlException class
}
}
}
在上面的循环中,我正在将某个节点(itemElementName)转换为XElement。
某些节点将是良好的XML并将进入XElement,但有些节点不会。
在CATCH中,我不仅要捕获标准的XmlException内容......我还想捕获当前Xml和字符串的摘录。
但是,如果我在将节点传递给XElement之前对节点进行任何类型的READ操作,它会向前移动读取器。
如何在不干扰其位置的情况下获取阅读器外部内容的“快照”?
答案 0 :(得分:10)
实际上,ReadSubtree将返回一个“包装”原始阅读器的阅读器。因此,通过新的阅读将最终推进原始的。 您必须将XmlReader视为仅向前阅读器,它根本无法返回。 至于您的场景,您可以向读者询问输入文件中的位置,而不是尝试记住部分XML。只需将其强制转换为IXmlLineInfo接口,它就有返回行和位置的方法。使用它你可以记住一些起始位置(在有问题的元素之前),然后记住错误的结束位置。然后从intput文件中读取该部分作为纯文本。
答案 1 :(得分:3)
不要在阅读器上使用任何“读取”操作 - 正如您所发现的那样,这可以推进它。使用对reader.HasValue
和reader.Value
等属性的调用来检查内容。在对象浏览器中查找“XmlReader”,您可以阅读很多属性。
编辑:我认为没有一种简单的方法可以简单地获取XML,可能是因为当前节点可能不是它自己的有效XML,例如XmlWhiteSpace,XmlText节点甚至是XmlAttribute。
答案 2 :(得分:1)
另一个想法:阅读外部XML(推进读者),然后从这个XML创建一个新的阅读器,它允许你回过头来#34;并处理当前节点的元素。
while (r.ReadToFollowing("ParentNode"))
{
parentXml = r.ReadOuterXml();
//since ReadOuterXml() advances the reader to the next parent node, create a new reader to read the remaining elements of the current parent
XmlReader r2 = XmlReader.Create(new StringReader(parentXml));
r2.ReadToFollowing("ChildNode");
childValue = r2.ReadElementContentAsString();
r2.Close();
}
答案 3 :(得分:1)
我所做的只是将元素读入XmlDocument,然后读取它。就我而言,我必须将流文档转换为HTML。我必须阅读一个内部元素来指定一个"样式"到父HTML元素。
答案 4 :(得分:0)
事实上,虽然Vitek Karas MSFT是对的,但Helena Kupkova在https://msdn.microsoft.com/en-us/library/aa302292.aspx上发布了一个灵巧的小型书签阅读器。这样可以使用缓存向后移动。
答案 5 :(得分:0)
与ReadSubtree类似的东西
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.MoveToContent();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "Field") // for example i need to read node field
{
XmlReader inner = reader.ReadSubtree(); // the reader stays in the same position
XElement El = XElement.Load(inner) as XElement;
inner.Close();
}
}
}
}