Python 如何更改具有命名前缀的XML元素的属性
我在试图编辑一个字符串中的XML属性时遇到了实际问题,该字符串包含一个带有名称前缀的XML元素 我正在尝试使用以下代码:Python 如何更改具有命名前缀的XML元素的属性,python,xml-parsing,namespaces,elementtree,Python,Xml Parsing,Namespaces,Elementtree,我在试图编辑一个字符串中的XML属性时遇到了实际问题,该字符串包含一个带有名称前缀的XML元素 我正在尝试使用以下代码: import xml.etree.ElementTree as ET def replace_xml_label(xml): element = ET.fromstring(xml) element.set('label', 'new_test_label') return ET.tostring(element).decode('ascii')
import xml.etree.ElementTree as ET
def replace_xml_label(xml):
element = ET.fromstring(xml)
element.set('label', 'new_test_label')
return ET.tostring(element).decode('ascii')
xml_1 = '<abc label="test label">test_value</abc>'
xml_2 = '<abc:option label="test label">test_value</abc:option>'
但是,我需要使用的XML元素的样式有一个类似于XML_2
的名称前缀,这会引发ParseError
:
print(replace_xml_label(xml_2))
Traceback (most recent call last):
... in XML parser.feed(text)
xml.etree.ElementTree.ParseError: unbound prefix: line 1, column 0
我的预期产出是:
<abc:option label="new_test_label">test_value</abc:option>
我是做错了什么,遗漏了一些明显的东西,还是仅仅使用了错误的工具
我更喜欢使用标准Python 3.4+库中提供的功能。当然,问题是由于未声明前缀。XML要求正确声明所有使用的名称空间前缀,否则文档不符合XML的条件,因此通常无法使用XML解析器库进行解析。因此,最终的解决方案是在当前生成类似XML的文档的一侧修复为生成格式良好的XML 在解析端解决此问题的一个可能的解决方法是,使用包含未声明前缀声明的父元素包装字符串,例如:
xml_2 = '<abc:option label="test label">test_value</abc:option>'
parent = '<foo xmlns:abc="bar">{}</foo>'
wellformed_xml = parent.format(xml_2)
result = replace_xml_label(wellformed_xml)
print(result)
xml\u 2='test\u value'
父项=“{}”
格式良好的xml=parent.format(xml_2)
结果=替换xml标签(格式正确的xml)
打印(结果)
我怀疑的主要问题是未声明的名称空间前缀
由于不可能在源代码处修复,并且输出需要采用我指定的格式,因此最好的解决方法似乎是在处理之前临时转换为简单标记,然后再转换回原始标记
xml_2 = '<abc:option label="test label">test_value</abc:option>'
# Convert first and last occurrences of tag to be without namespace.
original_tag = 'abc:option'
temp_tag = 'abc'
valid_xml = temp_tag.join(
xml_2.replace(original_tag, temp_tag, 1).rsplit(original_tag, 1)
)
# Replace label
modified_xml = replace_xml_label(valid_xml)
# Convert first and last occurrences of tag to re-add namespace.
output_xml = original_tag.join(
modified_xml.replace(temp_tag, original_tag, 1).rsplit(temp_tag, 1)
)
print(output_xml)
xml\u 2='test\u value'
#将标记的第一次和最后一次出现转换为不带命名空间。
原始标签='abc:选项'
临时标签='abc'
有效的\u xml=temp\u tag.join(
xml_2.replace(原始标签,临时标签,1).rsplit(原始标签,1)
)
#更换标签
修改的xml=替换xml标签(有效的xml)
#转换第一次和最后一次出现的标记以重新添加命名空间。
output\u xml=original\u tag.join(
修改的xml.replace(临时标记,原始标记,1).rsplit(临时标记,1)
)
打印(输出xml)
谢谢你的回答。不幸的是,(可以理解)添加了名称空间,并在选项
元素周围添加了ns0:
标记,从而产生了一个结果。我的问题似乎是试图使用无效的XML作为输入,同时也产生了一种不严格有效的格式。
xml_2 = '<abc:option label="test label">test_value</abc:option>'
parent = '<foo xmlns:abc="bar">{}</foo>'
wellformed_xml = parent.format(xml_2)
result = replace_xml_label(wellformed_xml)
print(result)
xml_2 = '<abc:option label="test label">test_value</abc:option>'
# Convert first and last occurrences of tag to be without namespace.
original_tag = 'abc:option'
temp_tag = 'abc'
valid_xml = temp_tag.join(
xml_2.replace(original_tag, temp_tag, 1).rsplit(original_tag, 1)
)
# Replace label
modified_xml = replace_xml_label(valid_xml)
# Convert first and last occurrences of tag to re-add namespace.
output_xml = original_tag.join(
modified_xml.replace(temp_tag, original_tag, 1).rsplit(temp_tag, 1)
)
print(output_xml)