我有一个包含以下XML内容的XML-Stream:
<WebError Key="A">
<Message>B</Message>
<Parameters>
<Parameter name="C">D</Parameter>
</Parameters>
</WebError>
我找不到让XmlReader
读取Key
属性的方法,以便reader.NodeType
为XmlNodeType.Attribute
和reader.LocalName
是"Key"
。
这是我初始化XmlReader
:
XmlReader.Create(stream, new XmlReaderSettings { CloseInput = true, IgnoreWhitespace = true });
然后,这个读者将通过几个方法级别,直到它进入我的解析器函数。
以下是我试图让读者阅读该元素的所有替代代码。从代码中剥离控制结构,因此您只能看到实际调用的函数。
首次尝试,通过MoveToFirstAttribute()
调用移至属性:
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
并没有让读者感动。通常用于解析内部subLevelReader
节点的副作用XmlElement
现在抓取整个WebError
节点,并且在subLevelReader
处置时,整个WebError
节点被转移。
第二次尝试,调用MoveToContent()
并搜索属性:
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
起始标记的末尾。
第三次尝试,在调用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
节点?
答案 0 :(得分:1)
This question(遗憾的是,在&#34; xmlreader c#属性&#34;的搜索结果中没有出现)包含an answer,这让我理解了问题:Read()
不要将读者放在属性上。首先移动到元素,然后移动到其内容,然后移动到其属性。只有这个订单有效。
如果您在<{strong> MoveToContent()
,MoveToAttribute("Key")
或MoveToNextAttribute()
之前致电MoveToFirstAttribute()
,则所有我的方法都有效,但不是Read()
因为它读取到Message
节点。
所以这是实际的代码:
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)
}
}
}
}
答案 1 :(得分:0)
最简单的方法是使用ReadToFollowing
和GetAttribute
方法。
reader.ReadToFollowing("WebError");
string keyAttr = reader.GetAttribute("Key");