Python XML按属性/子级排序
我正在使用Python(2.7/3.8)并处理一些比较复杂的XML。XML的顺序可能会有所不同,我正在构建一个函数作为排序规则(查看节点属性,然后查看节点子节点) 我已经看了一些不同的相关问题,但它们都不适用于我的场景:Python XML按属性/子级排序,python,xml,sorting,elementtree,Python,Xml,Sorting,Elementtree,我正在使用Python(2.7/3.8)并处理一些比较复杂的XML。XML的顺序可能会有所不同,我正在构建一个函数作为排序规则(查看节点属性,然后查看节点子节点) 我已经看了一些不同的相关问题,但它们都不适用于我的场景: 我可以使用key=lambda child:child.tag进行排序,但是我通常希望使用属性而不是标记名 在最基本的情况下,我希望能够按属性名排序,检查['id'、'label'、'value']中是否有任何属性存在,并将其用作键。不管怎样,我似乎不明白为什么chil
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"))
将xml.etree.ElementTree导入为etree
输入=“”
'''
root=etree.fromstring(输入)
root[:]=sorted(root,key=lambda-child:child.get('id'))
xmlstr=etree.tostring(root,encoding=“utf-8”,method=“xml”)
打印(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>
<root>
<node id="node5" />
<node id="node7" />
<node id="node10" />
</root>
编辑
正如deadshot所提到的,用int()包装child.get('id')确实解决了这个问题,但是代码还必须用于同时包含字母和数字的输入,例如id=“node1”、“node15”等
例如:
<root>
<node id="node10" />
<node id="node7" />
<node id="node5" />
</root>
预期:
<root>
<node id="5" />
<node id="7" />
<node id="10" />
</root>
<root>
<node id="node5" />
<node id="node7" />
<node id="node10" />
</root>
您应该将id
值转换为int
,并且您可以使用regex从id
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),并将其作为元组拆分为字符串/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))
def分割键(键):
regex=re.compile(r'^(?P.*?(-P\d*)$)
字母=正则表达式搜索(键).group('字母')或“”
numbers=regex.search(key.group('numbers')或0
返回(字母、整数(数字))
谢谢!解决了这个谜。。。现在,我如何使这两个int/string都适用,例如,如果id是,我已经用一个适用于format test、test123、123等字符串的答案更新了主要问题。您是否可以使用值id=“node1”、“node15”
和预期值发布示例output@deadshot-张贴。谢谢你的帮助。看起来我需要查看自然排序,所以我将从这里开始。@user2288151:请将问题和答案分开。如果您有其他或更详细的解决方案,请将其作为新答案发布。@mzjn,分开。谢谢