Синтаксический анализ xml, содержащего пространство имен по умолчанию, для получения значения элемента с использованием lxml
У меня есть строка 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> """
Я хочу извлечь все URL, присутствующие внутри <loc>
узел т.е. http://www.example.org/sitemap_1.xml.gz
Я попробовал этот код, но он не сказал ни слова
from lxml import etree
root = etree.fromstring(str1)
urls = root.xpath("//loc/text()")
print urls
[]
Я попытался проверить, правильно ли сформирован мой корневой узел. Я попытался это и получить ту же строку, что и 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>'
1 ответ
Это распространенная ошибка при работе с XML, имеющим пространство имен по умолчанию. Ваш XML имеет пространство имен по умолчанию, пространство имен, объявленное без префикса, здесь:
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
Обратите внимание, что не только элемент, в котором объявлено пространство имен по умолчанию, находится в этом пространстве имен, но и все дочерние элементы неявно наследуют пространство имен по умолчанию предка, если не указано иное (с использованием явного префикса пространства имен или локального пространства имен по умолчанию, которые указывают на другое пространство имен 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)
выход:
<loc xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
http://www.example.org/sitemap_1.xml.gz
</loc>