C# XmlReader读取XML节点丢失首个值的问题求助
问题:XmlReader读取XML时丢失第一个值的解决方法?
作为C#新手,我写了一段用XmlReader读取Operator.xml中Security节点下Operator、Password、Group文本值并通过Tuple返回的代码,但运行时总是丢失第一个值,不知道该怎么改。
我的代码:
public static Tuple<string, string, string> ReadSecurity() { XmlReader reader = XmlReader.Create("Operator.xml"); string sOperator = ""; string sPassword = ""; string sGroup = ""; while (reader.Read()) { if(reader.NodeType == XmlNodeType.Element && reader.Name == "Security") { while (reader.NodeType != XmlNodeType.EndElement) { reader.Read(); if (reader.NodeType == XmlNodeType.Text) { sOperator = reader.Value; } reader.Read(); if (reader.NodeType == XmlNodeType.Text) { sPassword = reader.Value; } reader.Read(); if (reader.NodeType == XmlNodeType.Text) { sGroup = reader.Value; } } } } return Tuple.Create(sOperator, sPassword, sGroup); }
XML示例:
<?xml version="1.0" encoding="utf-8"?> <Security ver="beta"> <Operator>Ted</Operator> <Password>password</Password> <Group>op</Group> </Security>
解决方案
你的问题出在盲目连续调用reader.Read(),没有正确对应元素节点和文本节点的关系,导致第一个值被跳过或者错误赋值。咱们拆解下原代码的问题:当找到<Security>元素后,你直接在循环里连续调用三次Read(),节点指针跳转毫无章法——比如第一次Read()会跳到<Operator>元素节点,第二次才到它的文本节点,这时候你把这个文本值赋给了sPassword,而sOperator根本没拿到正确的值,自然就丢失了。
下面给你两种靠谱的修正方案:
方案1:规范遍历子元素(通用型)
这种方法逻辑清晰,适合结构复杂或可能变化的XML:
public static Tuple<string, string, string> ReadSecurity() { string sOperator = ""; string sPassword = ""; string sGroup = ""; // 使用using确保XmlReader自动释放资源,避免内存泄漏 using (XmlReader reader = XmlReader.Create("Operator.xml")) { // 遍历找到Security元素 while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.Name == "Security") { // 遍历Security的子元素 while (reader.Read()) { // 碰到Security的结束标签就退出内层循环 if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "Security") { break; } // 处理每个子元素 if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { case "Operator": // 直接读取元素的文本内容,自动跳过起始/结束节点 sOperator = reader.ReadElementContentAsString(); break; case "Password": sPassword = reader.ReadElementContentAsString(); break; case "Group": sGroup = reader.ReadElementContentAsString(); break; } } } // 找到Security后直接退出外层循环,不用继续遍历 break; } } } return Tuple.Create(sOperator, sPassword, sGroup); }
方案2:直接定位元素(简洁型)
如果你的XML结构固定,用ReadToFollowing可以直接跳转到指定元素,代码更简洁:
public static Tuple<string, string, string> ReadSecurity() { string sOperator = ""; string sPassword = ""; string sGroup = ""; using (XmlReader reader = XmlReader.Create("Operator.xml")) { // 直接定位到Operator元素并读取值 if (reader.ReadToFollowing("Operator")) { sOperator = reader.ReadElementContentAsString(); } // 定位到Password元素 if (reader.ReadToFollowing("Password")) { sPassword = reader.ReadElementContentAsString(); } // 定位到Group元素 if (reader.ReadToFollowing("Group")) { sGroup = reader.ReadElementContentAsString(); } } return Tuple.Create(sOperator, sPassword, sGroup); }
两种方案都能解决你丢失第一个值的问题,按需选择就行~
内容的提问来源于stack exchange,提问作者ScaryMinds
相关产品推荐
相关产品推荐

