我正在更新xml文件,并希望使用ET.register_namespace
以下代码是我尝试过的:
ET.register_namespace('', "http://oval.mitre.org/XMLSchema/oval-definitions-5")
ET.register_namespace('', "http://oval.mitre.org/XMLSchema/oval-definitions-5#windows")
ET.register_namespace('', "http://oval.mitre.org/XMLSchema/oval-definitions-5#independent")
ns = "{http://oval.mitre.org/XMLSchema/oval-definitions-5}"
f = open ("def_ex.xml","ra")
tree = ET.parse(f)
root = tree.getroot()
for defn in root.iter('%stag' %ns):
if "patch" in defn.get("class"): #pick id attrib where class attrib is "patch"
print defn.get("id")
mirr_def = copy.deepcopy(defn)
defn.append(mirr_def)
tree.write("def_ex.xml")
exit()
但问题是third
命名空间会覆盖one
和two
,如下面的代码输出所示:
<ns0:tag>
.......
.......
</ns0:tag>
<ns1:tag1>
........
........
</ns1:tag1>
<tag2>
......
......
</tag2>
我的最后一个问题是,当存在不同的&#34;锚标签时,如何保留所有名称空间而不会互相覆盖#34;使用相同的URI?
已更新:def_ex.xml
<oval_definitions xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:windows-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#windows" xmlns:independent-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xsi:schemaLocation=" http://oval.mitre.org/XMLSchema/oval-definitions-5#windows windows-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#independent independent-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
<tag id="oval:def:1" class="inventory">
...........
...........
...........
</tag>
<tag1 xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#windows" id="oval:tst:1" version="1">
............
............
</tag1>
<tag2 xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" id="oval:tst:2" version="1">
............
............
</tag2>
</oval_definitions>
答案 0 :(得分:1)
正如@mu 無所说,你将无法使用 register_namespace 来实现你想要的东西,它明确防止出现重复的前缀。
我不确定您尝试做的是合法XML还是库支持,但是可以实现您想要的一种方法是实现 register_namespace的behaviour 直接:
xml.etree.ElementTree._namespace_map[uri] = prefix # Replace uri and prefix.
作为一个函数(从原始python库source code修改):
import re
import xml.etree.ElementTree
def register_namespace(prefix, uri):
if re.match("ns\d+$", prefix):
raise ValueError("Prefix format reserved for internal use")
xml.etree.ElementTree._namespace_map[uri] = prefix
我不建议这样做,因为它可能会以意想不到的方式破坏其他地方的库。
免责声明:我的代码尚未经过测试。
答案 1 :(得分:0)
您使用相同的前缀来定义所有3个URI。正如文档中所提到的,命名空间注册表是全局的,因此值被覆盖。
来自docs:
xml.etree.ElementTree.register_namespace(prefix, uri)
注册名称空间前缀。 注册表是全局,并且将删除给定前缀或命名空间URI的任何现有映射。 prefix是名称空间前缀。 uri是名称空间uri。如果可能的话,此命名空间中的标记和属性将使用给定的前缀进行序列化。
我建议您为每个URI添加名称空间,如下所示,并相应地使用它们
namespaces = {'ns1': 'http://oval.mitre.org/XMLSchema/oval-definitions-5',
'ns2': 'http://oval.mitre.org/XMLSchema/oval-definitions-5#windows',
'ns3': 'http://oval.mitre.org/XMLSchema/oval-definitions-5#independent'}
for prefix, uri in namespaces.items():
ET.register_namespace(prefix, uri)