当祖先提到名称空间时,如何使用 ElementTree 获取后代节点?

How do I get a descendant node using ElementTree when an ancestor mentions namespaces?

我有以下 xml:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    <url>
        <loc>https://news.mycoolsite.com/city/newyork/cat-bites-dog/articleshow/12345.pms</loc>
        <news:news>
            <news:publication>
                <news:name>New York Post</news:name>
                <news:language>en</news:language>
            </news:publication>
            <news:publication_date>2017-12-27T07:23:12+03:30</news:publication_date>
            <news:title>Cat bites dog</news:title>
            <news:keywords>Cat biting,Dog,Fluffy,Pongo,Broadway,Cat attack,</news:keywords>
        </news:news>
        <lastmod>2017-12-27T10:17:04+03:30</lastmod>
        <image:image>
            <image:loc>https://news.mycoolsite.com/city/newyork/cat-bites-dog/photo/12345.pms</image:loc>
        </image:image>
    </url>
</urlset>

如何使用 ElementTree 获取 'loc' 标签?

我试过以下方法:

import xml.etree.ElementTree as ET
tree = ET.parse('data.xml')
root = tree.getroot()
for child in root:
    print(child.tag, child.attrib)
    tags = []
    for loc in child.iter('loc'):
        print loc.tag
        tags.append(list)
    print("Found so many tags:" + str(len(tags)))

但是问题是好像没有找到任何标签! 问题是什么 ?它与使用的命名空间有什么关系吗?

编辑:如果我删除名称空间,那么我似乎找到了两个 loc 标签。所以问题似乎是我没有正确指定名称空间。但是第一个 loc 标签没有命名空间。那么如何正确指定命名空间呢?

您必须指定默认命名空间:

import xml.etree.ElementTree as ET
tree = ET.parse('data.xml')
root = tree.getroot()
for child in root:
    print(child.tag, child.attrib)
    tags = []
    for loc in child.iter('{http://www.sitemaps.org/schemas/sitemap/0.9}loc'):
        print loc.tag
        tags.append(list)
    print("Found so many tags:" + str(len(tags)))

命名空间确实有问题,推荐使用lxml

from lxml import etree

root = etree.parse("data.xml").getroot()
locs = root.findall(".//loc", root.nsmap)
image_locs = root.findall(".//image:loc", root.nsmap)