在C#或python中使用xpath解析xml
记几个笔记
文件后缀不一定要.xml,可以是任意后缀,只要内容是符合xml和格式即可解析出来
文件编码需要是utf-8,python和c#都需要,或者xml文件头有这样一句:<?xml version="1.0" encoding="utf-8"?>
一些比较复杂的文件,如果按照从上往下一层一层节点来解析,那么比较麻烦,但是通过xpath,指定节点来解析,那么就方便多了。
xml文件示例
<root>
<space>
<name> 江南 </name>
<subzone>
<zone>
<name> 桃溪 </name>
<ambient> jiangnan/forest_05 </ambient>
<music> Zone/xxxx1 </music>
</zone>
<zone>
<name> 木渎镇 </name>
<ambient> jiangnan/muduzheng </ambient>
<music> Jn_2/xxxx2 </music>
</zone>
<!--....还有很多zone !-->
<subzone>
<music> Space/Jiangnan_xxx </music>
<ambient> function/amb_wind </ambient>
<space>
</root>
C#版本解析
重要的点就是通过node.SelectSingleNode
来选择要的节点。
var xmldoc = new XmlDocument();
var xmlReader = XmlReader.Create(def_path);
xmldoc.Load(xmlReader);
var nodeList = xmldoc.FirstChild.ChildNodes;
Console.WriteLine($"读入xml,节点数:{nodeList.Count}");
StringBuilder builder = new StringBuilder();
builder.AppendLine($"场景chunk名称,音乐名,环境底噪,所属大区"); //场景chunk名称 文件夹名 资源名
foreach (XmlNode node in nodeList)
{
if (node.Name != "space")
{
Console.WriteLine("遇到特殊节点,未解析");
continue;
}
var subzone = node.SelectSingleNode("subzone");
var name = node.SelectSingleNode("name");
var music = node.SelectSingleNode("music");
var ambient = node.SelectSingleNode("ambient");
//....处理第1层节点的数据
if (subzone != null)
{
var zones = subzone.ChildNodes;
foreach (XmlLinkedNode ccNode in zones)
{
var name1 = ccNode.SelectSingleNode("name");
var music1 = ccNode.SelectSingleNode("music");
var ambient1 = ccNode.SelectSingleNode("ambient");
var subzone1 = ccNode.SelectSingleNode("subzone");
//..... 处理第2层节点的数据
//note 如果还有子子节点的话,需要再次处理
if (subzone1 != null)
{
Console.WriteLine($"第2层之后还有subzone, name:{tunkName} ,未解析");
}
}
}
}
python版本解析
python解析xml的文档:https://docs.python.org/zh-cn/2.7/library/xml.etree.elementtree.html
示例:
import xml.etree.ElementTree as ET
if __name__ == '__main__':
xml_path = r"D:\xxx\scene.xml"
tree = ET.parse(xml_path)
root = tree.getroot()
for child in root:
childs = child.getchildren()
print(childs,child.tag,child.text)
if child.tag == "space" and child.text and child.text:
pass