如何从 XmlReader 中读取而不向前移动它?
我遇到了这样的场景:
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 操作,它会将读取器向前移动。
如何获得阅读器 OuterXml 内容的“快照”而不干扰其位置?
I got this scenario:
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
}
}
}
In the above loop I'm transforming a certain node (itemElementName) into an XElement.
Some nodes will be good XML and will go into an XElement, however, some will not.
In the CATCH, I'd like to not only catch the standard XmlException stuff... I'd also like to catch an extract of the current Xml and a string.
However, if I do any kind of READ operation on the node before I pass it to the XElement, it moves the reader forward.
How can get a "snapshot" of the contents of the OuterXml of the reader without interfering with it's position?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
实际上 ReadSubtree 将返回一个“包装”原始阅读器的阅读器。因此,通读新书最终也会推进原来的书。
您必须将 XmlReader 视为仅前进的读取器,它根本无法后退。
对于您的场景,您可以向读者询问输入文件中的位置,而不是尝试记住 XML 的一部分。只需将其转换为 IXmlLineInfo 接口即可,它具有返回行和位置的方法。使用它,您可以记住一些起始位置(在有问题的元素之前),然后记住错误的结束位置。然后从输入文件中以纯文本形式读取该部分。
Actually ReadSubtree will return a reader which "wraps" the original reader. So reading through the new one will end up advancing the original one as well.
You must consider XmlReader as a forward only reader, it simply can't go back.
As for your scenario, instead of trying to remember part of the XML you can ask the reader for the position in the input file. Just cast it to IXmlLineInfo interface, it has methods to return line and position. Using this you could remember some starting position (before the element in question) and then the end position of the error. And then read that part from the intput file as a plain text.
另一个想法:读取外部 XML(使读取器前进),然后从此 XML 创建一个新的读取器,该读取器允许您“返回”并处理当前节点的元素。
Another idea: read the outer XML (which advances the reader), then create a new reader from this XML which allows you to "go back" and process the elements of the current node.
不要对读取器使用任何“读取”操作 - 正如您所发现的,这会提高它的性能。使用对
reader.HasValue
和reader.Value
等属性的调用来检查内容。在对象浏览器中查找“XmlReader”,您可以读取很多属性。编辑:我认为没有简单的方法来获取 XML,可能是因为当前节点本身可能不是有效的 XML,例如 XmlWhiteSpace、XmlText 节点甚至 XmlAttribute。
Don't use any 'Read' operation on the reader- as you've discovered, this advances it. Use calls to properties such as
reader.HasValue
andreader.Value
to inspect the contents. Look up 'XmlReader' in the object browser, there's quite a few properties you can read.Edit: I don't think there's an easy way of simply getting the XML, possibly because the current node may not be valid XML on it's own, such as an XmlWhiteSpace, XmlText node or even an XmlAttribute.
我所做的只是将元素读入 XmlDocument,然后读取该元素。就我而言,我必须将流程文档转换为 HTML。我必须读取内部元素才能为父 HTML 元素分配“样式”。
What I did was read just the element into an XmlDocument, and read that instead. In my case, I had to convert a flow document to HTML. I had to read a inner element to assign a "style" to the parent HTML element.
事实上,尽管 Vitek Karas MSFT 是正确的,Helena Kupkova 在 https://msdn.microsoft.com/en-us/library/aa302292.aspx。这使得可以使用缓存进行倒退。
In fact, although Vitek Karas MSFT is right, Helena Kupkova published a deft little XML Bookmark Reader on https://msdn.microsoft.com/en-us/library/aa302292.aspx. This enables going backwards using caching.
与 ReadSubtree 类似的东西
Something like that with ReadSubtree