gpt4 book ai didi

python - 用 beautifulsoup4 解析 xml,命名空间问题

转载 作者:太空狗 更新时间:2023-10-29 21:59:46 25 4
gpt4 key购买 nike

在使用 beautifulsoup4(根据需要安装 lxml)以 xml (word/document.xml) 形式解析 .docx 文件内容时,我遇到了一个问题。这部分来自 xml:

    ...
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
...

变成这样:

    ...
<graphic>
<graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic>
...

即使我只是解析文件并保存它,没有任何修改。像这样:

    from bs4 import BeautifulSoup
soup = BeautifulSoup(open(filepath_in), 'xml')
with open(filepath_out, "w+") as fd:
fd.write(str(soup))

或者从 python 控制台解析 xml。

对我来说,它看起来像命名空间,像这样声明,而不是在根文档节点中,被解析器吃掉。

这是错误还是功能?有没有办法在用 beautifulesoup4 解析时保留这些?还是我需要为此切换到其他东西?

更新 1: 如果使用一些正则表达式和文本替换,我将这些命名空间声明添加到根 document 节点,那么 beautifulsoup 会很好地解析它。但我仍然感兴趣是否可以在解析前不修改 xml 的情况下解决这个问题。

更新 2: 在试用 beutifulsoup 之后,我发现 namespace 声明仅在第一次出现时才被解析。意味着如果标签声明了命名空间,那么如果它的子标签有命名空间声明,它们将不会被解析。下面是带有输出的代码示例。

从 bs4 导入 BeautifulSoup

xmls = []
xmls.append("""<name1:tag xmlns:name1="namespace1" xmlns:name2="namespace2">
<name2:intag>
text
</name2:intag>
</name1:tag>
""")
xmls.append("""<tag>
<name2:intag xmlns:name2="namespace2">
text
</name2:intag>
</tag>
""")
xmls.append("""<name1:tag xmlns:name1="namespace1">
<name2:intag xmlns:name2="namespace2">
text
</name2:intag>
</name1:tag>
""")
for i, xml in enumerate(xmls):
print "============== xml {} ==============".format(i)
soup = BeautifulSoup(xml, "xml")
print soup

将产生输出:

============== xml 0 ==============
<?xml version="1.0" encoding="utf-8"?>
<name1:tag xmlns:name1="namespace1" xmlns:name2="namespace2">
<name2:intag>
text
</name2:intag>
</name1:tag>
============== xml 1 ==============
<?xml version="1.0" encoding="utf-8"?>
<tag>
<name2:intag xmlns:name2="namespace2">
text
</name2:intag>
</tag>
============== xml 2 ==============
<?xml version="1.0" encoding="utf-8"?>
<name1:tag xmlns:name1="namespace1">
<intag>
text
</intag>
</name1:tag>

看看,前两个 xml 是如何被正确解析的,而第三个中的第二个声明被吃掉了。

其实这个问题已经不涉及docx了。我的问题是这样的:这种行为是否硬编码在 beautifulsoup4 中,如果没有,那么我该如何更改它?

最佳答案

来自 W3C 推荐:

The Prefix provides the namespace prefix part of the qualified name, and MUST be associated with a namespace URI reference in a namespace declaration.

https://www.w3.org/TR/REC-xml-names/#ns-qualnames

所以我认为这是预期的行为:丢弃未声明的命名空间以优雅地允许对不遵守建议的文档进行一些解析。

关于python - 用 beautifulsoup4 解析 xml,命名空间问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24937831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com