解析包含默认命名空间的xml以使用lxml获取元素值

Anu*_*rma 5 python xml lxml elementtree default-namespace

我有一个像这样的xml字符串

str1 = """<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
    <loc>
        http://www.example.org/sitemap_1.xml.gz
    </loc>
    <lastmod>2015-07-01</lastmod>
</sitemap>
</sitemapindex> """
Run Code Online (Sandbox Code Playgroud)

我想提取<loc>节点内存在的所有网址,即http://www.example.org/sitemap_1.xml.gz

我尝试了这段代码,但没有说出来

from lxml import etree
root = etree.fromstring(str1)
urls = root.xpath("//loc/text()")
print urls
[]
Run Code Online (Sandbox Code Playgroud)

我试图检查我的根节点是否正确形成.我尝试了这个并获得与str1相同的字符串

etree.tostring(root)

'<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n<sitemap>\n<loc>http://www.example.org/sitemap_1.xml.gz</loc>\n<lastmod>2015-07-01</lastmod>\n</sitemap>\n</sitemapindex>'
Run Code Online (Sandbox Code Playgroud)

har*_*r07 9

处理具有默认命名空间的XML时,这是一个常见错误.您的XML具有默认名称空间,即没有前缀声明的名称空间,此处:

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
Run Code Online (Sandbox Code Playgroud)

请注意,除非另有说明,否则不仅声明默认名称空间声明的元素在该名称空间中,而且所有后代元素都会隐式继承祖先默认名称空间(使用显式名称空间前缀或指向不同名称空间uri的本地默认名称空间).这意味着,在这种情况下,所有元素都包含loc在默认命名空间中.

要在命名空间中选择元素,您需要为命名空间映射定义前缀并在XPath中正确使用前缀:

from lxml import etree
str1 = '''<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
    <loc>
        http://www.example.org/sitemap_1.xml.gz
    </loc>
    <lastmod>2015-07-01</lastmod>
</sitemap>
</sitemapindex>'''
root = etree.fromstring(str1)

ns = {"d" : "http://www.sitemaps.org/schemas/sitemap/0.9"}
url = root.xpath("//d:loc", namespaces=ns)[0]
print etree.tostring(url)
Run Code Online (Sandbox Code Playgroud)

输出:

<loc xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        http://www.example.org/sitemap_1.xml.gz
    </loc>
Run Code Online (Sandbox Code Playgroud)