我有一个xml文档,如下所示:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://someurl/Oldschema"
xsi:schemaLocation="http://someurl/Oldschema Oldschema.xsd"
xmlns:framework="http://someurl/Oldframework">
<framework:tag1> ... </framework:tag1>
<framework:tag2> <tagA> ... </tagA> </framwork:tag2>
</root>
我想要做的就是将http://someurl/Oldschema
更改为http://someurl/Newschema
,将http://someurl/Oldframework
更改为http://someurl/Newframework
,并保持其余文档不变。通过此帖子lxml: add namespace to input file的一些见解,我尝试了以下内容:
def fix_nsmap(nsmap, tag):
"""update the old nsmap-dict with the new schema-urls. Example:
fix_nsmap({"framework": "http://someurl/Oldframework",
None: "http://someurl/Oldschema"}) ==
{"framework": "http://someurl/Newframework",
None: "http://someurl/Newschema"}"""
...
from lxml import etree
root = etree.parse(XMLFILE).getroot()
root_tag = root.tag.split("}")[1]
nsmap = fix_nsmap(root.nsmap)
new_root = etree.Element(root_tag, nsmap=nsmap)
new_root[:] = root[:]
# ... fix xsi:schemaLocation
return etree.tostring(new_root, pretty_print=True, encoding="UTF-8",
xml_declaration=True)
这会在根标记中生成正确的“属性”,但对于文档的其余部分则完全失败:
<network xmlns:framework="http://someurl/Newframework"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://someurl/Newschema"
xsi:schemaLocation="http://someurl/Newschema Schema.xsd">
<ns0:tag1 xmlns:ns0="http://someurl/Oldframework"> ... </ns0:information>
<ns1:tag2 xmlns:ns1="http://someurl/Oldframework"
xmlns:ns2="http://someurl/Oldschema">
<ns2:tagA> ... </ns2:tagA>
</ns1:tag2>
我的做法有什么问题?有没有其他方法来更改名称空间?也许我可以使用xslt?
谢谢!
丹尼斯
答案 0 :(得分:-2)
我想做的就是将
http://someurl/Oldschema
更改为http://someurl/Newschema
,将http://someurl/Oldframework
更改为http://someurl/Newframework
,并保留其余文档。
我会做一个简单的文本搜索和替换操作。它比摆弄XML节点容易得多。像这样:
with open("input.xml", "r") as infile, open("output.xml", "w") as outfile:
data = infile.read()
data = data.replace("http://someurl/Oldschema", "http://someurl/Newschema")
data = data.replace("http://someurl/Oldframework", "http://someurl/Newframework")
outfile.write(data)
您受到启发的other question是关于添加新命名空间(并保留旧命名空间)。但是您正在尝试修改现有的名称空间声明。在这种情况下,创建新的根元素并复制子节点不起作用。
这一行:
new_root[:] = root[:]
将原始根元素的子元素转换为新根元素的子元素。但是这些子节点仍然与旧的命名空间相关联。所以他们也必须进行修改/重新创建。我想有可能想出一个合理的方法来做到这一点,但我认为你不需要它。文字搜索和替换就足够了,恕我直言。