微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

查找 lxml 的命名空间 URI

如何解决查找 lxml 的命名空间 URI

我正在使用 lxml 解析带有以下代码的 XML 产品提要:

namespace = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}
data = [loc.text for loc in tree.xpath("//sm:urlset/sm:url/sm:loc",namespaces=namespace)]

这适用于我用作输入的大多数提要,但我偶尔会发现带有其他命名空间的提要,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<urlset
      xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="https://www.sitemaps.org/schemas/sitemap/0.9
            https://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

<url>
  <loc>https://www.example.com/</loc>
  <priority>1.00</priority>
</url>

从我读到的内容来看,我需要将这里的附加命名空间(我猜是 xmlns:xsi)添加到命名空间字典中,以使我的 xpath 能够处理多个命名空间。 但是,这对我来说不是一个长期的解决方案,因为我将来可能会遇到其他不同的命名空间 - 有没有办法让我搜索/检测甚至删除命名空间?元素树总是相同的,所以我的 xpath 不会改变。

谢谢

解决方法

您不需要映射 xsi 前缀;这仅适用于 xsi:schemaLocation 属性。

您当前的映射与输入文件的区别在于,XML 的默认命名空间中的“https”中有一个“s”。

要处理两个命名空间 URI(或实际上 urlset 可能具有的任何其他命名空间 URI)是首先获取根元素的命名空间 URI,然后在您的 dict 映射中使用它...

from lxml import etree

tree = etree.parse("input.xml")

root_ns_uri = tree.xpath("namespace-uri()")

namespace = {"sm": root_ns_uri}
data = [loc.text for loc in tree.xpath("//sm:urlset/sm:url/sm:loc",namespaces=namespace)]

print(data)

打印...

['https://www.example.com/']

如果 urlset 并不总是根元素,您可能想要做这样的事情来代替...

root_ns_uri = tree.xpath("namespace-uri(//*[local-name()='urlset'])")

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。