如何解决Python XML按属性/子级排序
我正在使用Python(2.7 / 3.8)并使用一些比较在一起的复杂XML。 XML的顺序可以不同,我正在构建一个函数作为排序规则(先查看节点属性,再查看节点子节点)。
我看了几个不同的相关问题,但都不适用于我的情况:
我可以使用key=lambda child: child.tag
进行排序,但是我通常希望使用属性而不是标签名称。
在最基本的情况下,我希望能够按属性名称进行排序,检查['id','label','value']中的任何一个是否作为属性存在,并将其用作键。无论如何,我似乎无法弄清楚为什么child.tag可以进行排序,但是child.get('id')却不能。
import xml.etree.ElementTree as etree
input = '''
<root>
<node id="7"></node>
<node id="10"></node>
<node id="5"></node>
</root>
'''
root = etree.fromstring(input)
root[:] = sorted(root,key=lambda child: child.get('id'))
xmlstr = etree.tostring(root,encoding="utf-8",method="xml")
print(xmlstr.decode("utf-8"))
哪个返回:
<root>
<node id="7" />
<node id="5" />
<node id="10" />
</root>
预期:
<root>
<node id="5" />
<node id="7" />
<node id="10" />
</root>
编辑
如前文所述,用int()包装child.get('id')确实可以解决该问题,但是该代码还必须对同时具有字母和数字的输入起作用,例如id =“ node1”, node15”,等等。
例如:
<root>
<node id="node10" />
<node id="node7" />
<node id="node5" />
</root>
预期:
<root>
<node id="node5" />
<node id="node7" />
<node id="node10" />
</root>
解决方法
您应该将id
的值转换为int
,然后可以使用正则表达式从id
提取didgit
import re
root[:] = sorted(root,key=lambda child: int(re.search('\d+',child.get('id')).group()))
xmlstr = etree.tostring(root,encoding="utf-8",method="xml")
print(xmlstr.decode("utf-8"))
输出:
<root>
<node id="node5" />
<node id="node7" />
<node id="node10" />
</root>
,
要进一步建立Deadshot的方法,我使用下面的split_key函数,我可以随时提取一个字符串(test,test123、123)并将其作为一个元组拆分到string / int部分,以允许易于通过排序方法进行排序。
def split_key(key):
regex = re.compile(r'^(?P<letters>.*?)(?P<numbers>\d*)$')
letters = regex.search(key).group('letters') or ''
numbers = regex.search(key).group('numbers') or 0
return (letters,int(numbers))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。