如何使用lxml的objectify去除XML标签与属性名中的短横线
解决方案
方法1:递归转换XML节点名称后再生成objectify对象(推荐,不会误修改属性值内容)
该方案会统一把所有标签名、属性名里的短横线替换为下划线,处理完成后可以直接用点语法访问对应元素和属性:
from lxml import etree, objectify def replace_hyphens_in_xml(element): # 替换当前标签名的短横线为下划线 element.tag = element.tag.replace('-', '_') # 替换所有属性名的短横线为下划线 for attr_name in list(element.attrib.keys()): if '-' in attr_name: new_attr_name = attr_name.replace('-', '_') element.attrib[new_attr_name] = element.attrib.pop(attr_name) # 递归处理所有子节点 for child in element: replace_hyphens_in_xml(child) return element # 原始XML字符串 xml_string = """<root> <foo-foo name="example" foo-description="description"> <bar doc-name="name" /> <test tag="test" /> </foo-foo> </root>""" # 先解析为etree节点处理名称,再转成objectify对象 root_etree = etree.fromstring(xml_string.encode('utf-8')) processed_etree = replace_hyphens_in_xml(root_etree) obj = objectify.fromstring(etree.tostring(processed_etree)) # 现在可以直接用下划线访问对应元素和属性 print(obj.foo_foo.attrib['foo_description']) # 输出 description print(obj.foo_foo.bar.attrib['doc_name']) # 输出 name
方法2:临时访问带短横线的元素/属性(不需要修改原始结构)
如果不需要全局替换名称,也可以用方括号语法直接访问带特殊字符的标签和属性:
from lxml import objectify xml_string = """<root> <foo-foo name="example" foo-description="description"> <bar doc-name="name" /> <test tag="test" /> </foo-foo> </root>""" obj = objectify.fromstring(xml_string) # 方括号访问带短横线的标签 foo_foo = obj['foo-foo'] # get方法访问带短横线的属性 print(foo_foo.get('foo-description')) # 输出 description print(foo_foo.bar.get('doc-name')) # 输出 name
内容的提问来源于stack exchange,提问作者Muhammad Shoaib
相关产品推荐
相关产品推荐

