如何让 XmlReader 读取 C# 中的属性? [英] How to make an XmlReader read the attributes in C#?

查看:19
本文介绍了如何让 XmlReader 读取 C# 中的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含以下 XML 内容的 XML-Stream:

I have an XML-Stream that contains the following XML content:

<WebError Key="A">
  <Message>B</Message>
  <Parameters>
    <Parameter name="C">D</Parameter>
  </Parameters>
</WebError>

我找不到让 XmlReader 读取到 Key 属性的方法,因此 reader.NodeTypeXmlNodeType.Attributereader.LocalName"Key".

I can't find a way to get an XmlReader to read to the Key attribute, so that reader.NodeType is XmlNodeType.Attribute and reader.LocalName is "Key".

这是我如何初始化我的 XmlReader:

This is how I initialize my XmlReader:

XmlReader.Create(stream, new XmlReaderSettings { CloseInput = true, IgnoreWhitespace = true });

这个阅读器然后通过几个方法级别,直到它到达我的解析器函数.

This reader then is passed through several method levels, until it gets to my parser function.

这是我试图让读者阅读该元素的所有替代代码.从代码中剥离了控制结构,因此您只能看到实际调用的函数.

Here is all the alternative code I tried to get the reader to read that element. Is stripped the control structures from the code, so you can only see the functions that are actually called.

第一次尝试,通过MoveToFirstAttribute()调用移动到属性:

First attempt, move to attributes by MoveToFirstAttribute() call:

reader.Read(); // true
reader.IsStartElement("WebError"); // true
using (var nodeReader = reader.ReadSubtree()) {
  nodeReader.HasAttributes; // true
  nodeReader.MoveToFirstAttribute(); // false
  nodeReader.Read(); // true
  nodeReader.NodeType; // XmlNodeType.Element
  nodeReader.LocalName; // "WebError"
  using (var subLevelReader = nodeReader.ReadSubtree()) {
  }
  nodeReader.Read(); // false
}

很明显,MoveToFirstAttribute 不会移动阅读器.作为副作用,通常用于解析内部 XmlElement 节点的 subLevelReader 现在会抓取整个 WebError 节点,并且当 subLevelReader 被处理,整个 WebError 节点被跨过.

So obviously, MoveToFirstAttribute does not move the reader. As a side effect subLevelReader that is usually used to parse inner XmlElement nodes now grabs the whole WebError node, and when subLevelReader is disposed, the whole WebError node is stepped over.

第二次尝试,调用 MoveToContent() 并搜索属性:

Second attempt, call MoveToContent() and search for attributes:

reader.Read(); // true
reader.IsStartElement("WebError"); // true
using (var nodeReader = reader.ReadSubtree()) {
  nodeReader.MoveToContent(); // XmlNodeType.Element
  nodeReader.LocalName; // "WebError"
  nodeReader.Read(); // true
  nodeReader.NodeType; // XmlNodeType.Element
  nodeReader.LocalName; // "Message"
  ...
}

显然,当我调用 MoveToContent() 时,我已经取得了太多进展,因为它移动到了 WebError 起始标记的末尾.

Obviously I progressed too far already when I called MoveToContent() because it moved to the end of the WebError starting tag.

第三次尝试,在调用MoveToContent()之前读取属性:

Third attempt, read attributes before calling MoveToContent():

reader.Read(); // true
reader.IsStartElement("WebError"); // true
using (var nodeReader = reader.ReadSubtree()) {
  nodeReader.MoveToAttribute("Key"); // false
  nodeReader.MoveToContent(); // XmlNodeType.Element
  nodeReader.LocalName; // "WebError"
  nodeReader.Read(); // true
  nodeReader.NodeType; // XmlNodeType.Element
  nodeReader.LocalName; // "Message"
  ...
}

这也不起作用.那么,我如何到达 WebError@Key 节点?

This does not work either. So, how do I get to the WebError@Key node?

推荐答案

这个问题(不幸的是没有出现在xmlreader c# 属性"的搜索结果中)包含一个答案,这让我明白了这个问题:Read() 不会将阅读器定位在属性上.首先移至元素,然后移至其内容,然后移至其属性.只有这个顺序有效.

This question (which unfortunately does not turn up in the search results for "xmlreader c# attribute") contains an answer which made me understand the problem: Read() does not position the reader at an attribute. You first move to an element, then move to its content, then move to its attributes. Only this order works.

如果你调用 MoveToContent() before MoveToAttribute("Key")MoveToNextAttribute()MoveToFirstAttribute(),但不是 Read(),因为它读取到 Message 节点.

Turns out all my approaches work if you call MoveToContent() before MoveToAttribute("Key"), MoveToNextAttribute() or MoveToFirstAttribute(), but not Read() yet because that reads to the Message node.

这是实际的代码:

while (reader.Read()) {
  if (!reader.IsStartElement("WebError")) { continue; }

  // We found the WebError node
  using (var nodeReader = reader.ReadSubtree()) {
    nodeReader.MoveToContent();

    // Read the attributes
    while (nodeReader.MoveToNextAttribute()) {
      var nodeName = nodeReader.LocalName;
      if (nodeName == "Key") {
        m_Key = nodeReader.Value; // "A"
        break;
      }
    }

    // Read the XML sub nodes
    while (nodeReader.Read()) {
      if (nodeReader.NodeType != XmlNodeType.Element) { continue; }

      using (var subLevelReader = nodeReader.ReadSubtree()) {
        // Parse sub levels of XML (Message, Parameters)
      }
    }
  }
}

这篇关于如何让 XmlReader 读取 C# 中的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆