【问题标题】:Python lxml tostring not print nsmapPython lxml tostring不打印nsmap
【发布时间】:2020-04-09 12:43:56
【问题描述】:

我正在使用 Doxygen XML 解析器。我的问题其实很简单,我需要使用 LXML 的tostring 来获取 XML 元素的原始内容。

我可以使用 ETree,但我切换到 LMXL,所以我得到了strip_tags

假设我有这个 XML 文件:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.16">
  <child2/>
  <child3/>
</root>

我这样做:

tree = ET.parse('new1.xml')
root = tree.getroot()
child3 = root.find("./child3")

objectify.deannotate(child3, cleanup_namespaces=True, xsi=True, pytype=True)
etree.cleanup_namespaces(child3)
child3.nsmap.clear()
etree.strip_attributes(child3, 'nsmap') 

print(ET.tostring(child3, encoding='unicode', pretty_print=True))

这是我得到的:

<child3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

这就是我想要的:

<child3/>

是否有一个选项可以将字符串转换为 NOT 打印 nsmap?

我试过了:

如果我尝试

root.nsmap = None

我得到一个例外:

AttributeError: attribute 'nsmap' of 'lxml.etree._Element' objects is not writable

我在 Windows 10 中使用 Python 3.7 64 位。

谢谢。

【问题讨论】:

  • root = etree.Element("root", nsmap=nsmap) 更改为root = etree.Element("root") 似乎是显而易见的事情。
  • 好吧,也许 like 是最小工作示例的一部分,而 t 不是我实际代码的一部分。在我的问题的底部,我解释了真正的 XML 来自哪里。当真正的 XML 被解析时,我得到了 'nsmap' 属性集。所以我的问题是:给定一个设置了 'nsmap' 属性的 Element 对象,我如何让 tostring *NOT 打印它。
  • 演示文档中的根元素有一个xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 声明,但实际上并未使用命名空间。因此,将通过调用etree.cleanup_namespaces(root) 删除声明。 lxml.de/api/lxml.etree-module.html#cleanup_namespaces
  • 是的,这是真的,但不是在我的实际代码中,正如我在问题中明确所说的那样。所以你的解决方案是修复我的例子?有关如何解决手头问题的任何建议?
  • 我不确定你的意思。如果该示例不能正确展示您的实际问题,那么是的,您应该“修复”该示例(提供minimal reproducible example)。顺便说一句,当我试图理解问题所在时,你称之为“完整上下文”的部分问题根本没有帮助。似乎与我无关。

标签: python lxml


【解决方案1】:

在 XML 文档中,http://www.w3.org/2001/XMLSchema 命名空间正在使用中。 xsi:noNamespaceSchemaLocation 属性绑定到该命名空间。

为了获得想要的输出,您必须 1) 删除 xsi:noNamespaceSchemaLocation 属性和 2) 删除命名空间的声明。

from lxml import etree

tree = etree.parse('new1.xml')
root = tree.getroot()

# Remove the xsi:noNamespaceSchemaLocation attribute
del root.attrib["{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation"]

# Remove the declaration for the now unused namespace. Must be done on the root element
etree.cleanup_namespaces(root)

child3 = root.find("./child3")

# Print child3
print(etree.tostring(child3, encoding='unicode', pretty_print=True))

# Print the whole document
print(etree.tostring(root, encoding='unicode', pretty_print=True))

输出:

<child3/>


<root version="1.8.16">
  <child2/>
  <child3/>
</root>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 2016-05-10
    • 2016-10-18
    相关资源
    最近更新 更多