Python:在XML中将所有标签名中的连字符替换为下划线
我有一个格式不太规范的XML文件,里面的标签名有连字符,我想把这些连字符替换成下划线(这样我就可以用lxml.objectify来处理它)。我想替换所有的标签名,包括里面的子标签。
这是一个示例XML:
<job>
<server>
<cpu-set>
</cpu-set>
</server>
<ip-routings>
</ip-routings>
</job>
我想用一种干净的方式来转换这个XML(不使用正则表达式,而是用像lxml这样的XML库),变成这个样子:
<job>
<server>
<cpu_set>
</cpu_set>
</server>
<ip_routings>
</ip_routings>
</job>
有什么好的方法可以用Python来做到这一点吗?
2 个回答
1
我知道这不是Python,但对我来说,这很像Python的风格:使用Mono的C#解释器:
using System.Xml.Linq;
var doc = XDocument.Load(Console.In);
foreach(var node in doc.Descendants().Reverse())
node.ReplaceWith(new XElement(
node.Name.Namespace + node.Name.LocalName.Replace("-","_"),
node.Attributes(),
node.Nodes()));
doc.Save(Console.Out);
这个工具有一些重要的特点,这些特点在没有现成的XML库的情况下很难实现:
- 支持混合元素(可以包含文本和子元素)
- 保留命名空间
- 保留属性
- 支持所有XML 2.0的功能(比如CDATA、未解析的内容、实体引用等)
- 还有更多类似的功能
演示:
输入文件:input.xml:
<?xml version="1.0"?>
<job xmlns:ex="test">
<server attr1="first" attr2="second">
<ex:cpu-set>
</ex:cpu-set>
</server>
<ip-routings>
contained <mixed/>text
</ip-routings>
</job>
运行csharp -r:System.Xml.Linq test < input.xml
的输出结果:
<?xml version="1.0" encoding="utf-8"?>
<job xmlns:ex="test">
<server attr1="first" attr2="second">
<ex:cpu_set />
</server>
<ip_routings>
contained <mixed />text
</ip_routings>
</job>
5
使用xpath来找到带有连字符的元素,并重新写标签:
from lxml import etree
data = """<job>
<server>
<cpu-set>
</cpu-set>
</server>
<ip-routings>
</ip-routings>
</job>"""
doc = etree.XML(data)
for e in doc.xpath('//*[contains(local-name(),"-")]'):
e.tag = e.tag.replace('-','_')
print etree.tostring(doc)
结果是:
<job>
<server>
<cpu_set>
</cpu_set>
</server>
<ip_routings>
</ip_routings>
</job>