如何获取XML中特定节点及其属性信息?解决InnerText与属性获取问题
提取XML特定节点的名称、值及属性
问题描述
我有一个存储角色信息的XML文件,想要获取特定节点的名称、值及其属性。尝试使用XmlReader未成功,使用InnerText会返回所有子节点内容,且无法获取BodyPart节点的PartNumber属性值。
XML文档
<Character ID="11000"> <HP>100</HP> <Name>name</Name> <BodyParts> <BodyPart PartNumber="1">LArm</BodyPart> <BodyPart PartNumber="2">RArm</BodyPart> <BodyPart PartNumber="3">Head</BodyPart> <BodyPart PartNumber="4">Body</BodyPart> <BodyPart PartNumber="5">RLeg</BodyPart> <BodyPart PartNumber="6">LLeg</BodyPart> </BodyParts> </Character>
现有代码
static XmlDocument doc = new XmlDocument(); public static void F() { foreach(string FilePath in Directory.GetFiles("XML.Resources/Characters")) { doc.Load(FilePath); foreach(XmlNode Node in doc.ChildNodes) { Console.WriteLine(Node.InnerText); foreach(XmlAttribute Atributo in Node.Attributes) { Console.WriteLine(Atributo.Name); Console.WriteLine(Atributo.Value); } } } }
现有输出结果
100nameLArmRArmHeadBodyRLegLLeg ID 11000
解决方案
可以通过精准定位节点并分层遍历的方式,获取每个节点的名称、值及属性,避免InnerText一次性返回所有内容。以下是修改后的代码:
static XmlDocument doc = new XmlDocument(); public static void F() { foreach(string FilePath in Directory.GetFiles("XML.Resources/Characters")) { doc.Load(FilePath); // 精准获取根节点Character XmlNode characterNode = doc.SelectSingleNode("/Character"); if(characterNode == null) continue; // 输出根节点属性 Console.WriteLine("=== 角色根节点属性 ==="); foreach(XmlAttribute attr in characterNode.Attributes) { Console.WriteLine($"{attr.Name}: {attr.Value}"); } // 遍历根节点的子元素 foreach(XmlNode childNode in characterNode.ChildNodes) { // 仅处理元素节点,跳过空白和注释节点 if(childNode.NodeType != XmlNodeType.Element) continue; Console.WriteLine($"\n=== 节点:{childNode.Name} ==="); // 处理BodyParts节点,遍历其下的BodyPart子节点 if(childNode.Name == "BodyParts") { foreach(XmlNode bodyPartNode in childNode.ChildNodes) { if(bodyPartNode.NodeType != XmlNodeType.Element) continue; Console.WriteLine($"节点名称:{bodyPartNode.Name}"); Console.WriteLine($"节点值:{bodyPartNode.InnerText}"); // 获取并输出PartNumber属性 XmlAttribute partNumAttr = bodyPartNode.Attributes["PartNumber"]; if(partNumAttr != null) { Console.WriteLine($"属性:{partNumAttr.Name} = {partNumAttr.Value}"); } Console.WriteLine("---"); } } else { // 普通节点直接输出值 Console.WriteLine($"节点值:{childNode.InnerText}"); } } } }
代码说明
- 使用
SelectSingleNode("/Character")直接定位根节点,避免遍历doc.ChildNodes时包含XML声明等无关节点 - 过滤
XmlNodeType.Element类型的节点,跳过XML中的空白节点,避免无效遍历 - 针对
BodyParts节点做特殊处理,遍历其下的每个BodyPart子节点,分别提取节点名称、文本值和PartNumber属性 - 根节点属性和普通节点(HP、Name)的信息分层输出,结构更清晰
内容的提问来源于stack exchange,提问作者Miguel Ángel
相关产品推荐
相关产品推荐

