xmlns = “” 在解析 XML 文件时消失

xmlns = "" disappears when parsing over xml file

提问人:Sandra 提问时间:3/20/2023 最后编辑:mzjnSandra 更新时间:6/16/2023 访问量:147

问:

我正在解析一个看起来像这样的 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<!--WFVersion:53.0-->
<Tag1 xmlns="http:www.intel.com/example">
  <Tag2 attrib1="100"
    attrib2="400000"
        xmlns="" />

我需要更改文件中的一个属性,同时保留空的 xml 命名空间属性 (xmlns = “”)。 目前,我正在使用

ET.register_namespace("", "http:www.intel.com/example")

以保留非空的 XML 命名空间。

总的来说,我的代码如下所示:

import xml.etree.ElementTree as ET

xml = ET.parse(file_path)
ET.register_namespace("", "http:www.intel.com/example")
#change something
with open(workflow_path, 'w+') as f: 
    f.write(ET.tostring(xml.getroot()).decode())

问题在于写入操作删除了空的 xml 命名空间(即使没有对 xml 进行任何更改)

python xml xml 解析 elementtree xml-namespaces

评论

0赞 Yitzhak Khabinsky 3/20/2023
为什么不将 XSLT 用于任务?
0赞 jdweng 3/20/2023
是 etree 库导致了问题。使用 xml 库时,为什么要将 xml 转换为字符串?
0赞 Sandra 3/20/2023
@jdweng当我使用 xml.write 而不是使用 tostring 编写时,我遇到了同样的问题
1赞 Daniel Haley 3/20/2023
似乎是 ElementTree 错误。你能用lxml来代替吗?如果您不注册默认命名空间,它似乎可以正常工作。http:www.intel.com/example
0赞 jdweng 3/20/2023
为什么要使用 w+ 追加到现有文件。您需要做的就是 xml.Write('filename')。您正在使用 XML 库。当您更改某些内容时,文档也会更改。

答:

0赞 Daniel Haley 3/22/2023 #1

如果您可以使用 lxml,则以下操作似乎有效......

XML 输入 (scratch_22.xml)

<!--WFVersion:53.0-->
<Tag1 xmlns="http:www.intel.com/example">
  <Tag2 attrib1="100"
    attrib2="400000"
        xmlns="" />
</Tag1>

from lxml import etree

xml = etree.parse("scratch_22.xml")

tag2 = xml.find("Tag2")
tag2.set("attrib1", "i was changed")

etree.dump(xml.getroot())

输出(转储到控制台,但 .write() 也可以工作)

<Tag1 xmlns="http:www.intel.com/example">
  <Tag2 xmlns="" attrib1="i was changed" attrib2="400000"/>
</Tag1>
0赞 Hermann12 6/15/2023 #2

尝试使用 xml.etree.ElementTree 作为解决方法:


import xml.etree.ElementTree as ET
from io import StringIO

xmlstr = """<?xml version="1.0" encoding="UTF-8"?>
<!--WFVersion:53.0-->
<Tag1 xmlns="http://www.intel.com/example">
  <Tag2 attrib1="100"
    attrib2="400000"
        xmlns="" />
</Tag1>"""
f = StringIO(xmlstr)

tree = ET.parse(f)
root = tree.getroot()
ET.dump(root)

ET.register_namespace("", "http://www.intel.com/example")
Tag2 = root.find("Tag2")
Tag2.set('xmlns', "")

#change something
tree.write('namespace.xml', xml_declaration=True, encoding="UTF-8")
ET.dump(tree)

转储:

<Tag1 xmlns="http://www.intel.com/example">
  <Tag2 attrib1="100" attrib2="400000" />
</Tag1>
<Tag1 xmlns="http://www.intel.com/example">
  <Tag2 attrib1="100" attrib2="400000" xmlns="" />
</Tag1>

输出文件:


<?xml version='1.0' encoding='UTF-8'?>
<Tag1 xmlns="http://www.intel.com/example">
  <Tag2 attrib1="100" attrib2="400000" xmlns="" />
</Tag1>

评论

1赞 mzjn 6/15/2023
这不会保留 .xmlns=""
0赞 Hermann12 6/16/2023
@mzjn 谢谢,现在我明白了你的意思并更新了我的答案。
0赞 mzjn 6/16/2023
好的,但这不是一个通用的解决方案,因为它仅在特殊情况下(在元素上)保留。 可能发生在任何元素上。xmlns=""Tag2xmlns=""