Как удалить атрибут из корневого элемента в Python xml etree ElementTree

Мой файл содержит следующие данные:

Оригинал:

<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <changefreq>daily</changefreq> <loc>http://www.example.com</loc></url></urlset>

Ожидаемое:

<?xml version="1.0" encoding="UTF-8"?><urlset> <url> <changefreq>daily</changefreq> <loc>http://www.example.com</loc></url></urlset>

Я использую etree для разбора файла и хочу удалить атрибут из корневого элемента 'urlset'

import xml.etree.ElementTree as ET

tree = ET.parse("/Users/hsyang/Downloads/VI-0-11-14-2016_20.xml")
root = tree.getroot()

print root.attrib
>> {}

root.attrib.pop("xmlns", None)

print root.attrib
>> {}
ET.tostring(root)

Я думал, что должен был получить {xmlns: " http://www.sitemaps.org/schemas/sitemap/0.9"}, когда я печатаю root.attrib в первый раз, но я получил пустой словарь. Может кто-нибудь помочь?

Ценить это!

2 ответа

Решение

xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" выглядит как обычный атрибут, но это особый случай, а именно объявление пространства имен.

Удаление, добавление или изменение пространств имен может быть довольно сложным. "Нормальные" атрибуты хранятся в элементе, доступном для записи attrib имущество. Сопоставления пространств имен, с другой стороны, недоступны через API (в библиотеке lxml элементы действительно имеют nsmap свойство, но это только для чтения).

Я предлагаю простую текстовую операцию поиска и замены, аналогичную ответу на Изменить пространства имен в данном документе xml с помощью lxml. Что-то вроде этого:

with open("input.xml", "r") as infile, open("output.xml", "w") as outfile:
    data = infile.read()
    data = data.replace(' xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '')
    outfile.write(data)

Смотрите также Как вставить пространство имен и префиксы в строку XML с помощью Python?,

В стандартной библиотеке xml.etree.ElementTree нет специального метода для удаления атрибута, но все атрибуты хранятся в attrib который является dict и любой атрибут может быть удален из attrib как ключ от dict:

    import xml.etree.ElementTree as ET

    tree = ET.parse(file_path)
    root = tree.getroot()      

    print(root.attrib)  # {'xyz': '123'}

    root.attrib.pop("xyz", None)  # None is to not raise an exception if xyz does not exist

    print(root.attrib)  # {}

    ET.tostring(root)
    '<urlset> <url> <changefreq>daily</changefreq> <loc>http://www.example.com</loc></url></urlset>'
Другие вопросы по тегам