Строго говоря, у меня есть ответ на свой вопрос, но потребуется больше работы, чтобы реализовать его так, как мне бы хотелось. Вот как это сделать.
Создайте подкласс XMLFormatter (или HTMLFormatter, если вы работаете с HTML), назовите его как хотите. Я выбрал «Сортировать атрибуты». Напишите функцию «attribute», чтобы она возвращала список кортежей: [(attribute1, value1), (attribute2, value2), et c.] В нужном вам порядке. Мой может выглядеть многословно, но я делаю это так, потому что я работаю с очень непоследовательным XML.
from bs4 import BeautifulSoup
from bs4.formatter import XMLFormatter
class SortAttributes(XMLFormatter):
def attributes(self, tag):
"""Reorder a tag's attributes however you want."""
attrib_order = ['id', 'head', 'postag', 'relation', 'form', 'lemma']
new_order = []
for element in attrib_order:
if element in tag.attrs:
new_order.append((element, tag[element]))
for pair in tag.attrs.items():
if pair not in new_order:
new_order.append(pair)
return new_order
xml_string = '''
<word form="συ" head="2610" id="2357" lemma="συ" postag="p-s----n-" relation="ExD_AP"/>
'''
soup = BeautifulSoup(xml_string, 'xml')
print(soup.encode(formatter=SortAttributes()))
Это выдаст то, что я хочу:
<word id="2357" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/>
Удобно, я могу сделать это для всего документа с тем же методом кодирования. Но если я напишу это в файл в виде строки, то все теги будут просто соединены друг с другом. Пример будет таким:
<sentence id="783"><word id="2357" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/><word id="2358" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/><word id="2359" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/></sentence>
Вместо того, что я предпочитаю:
<sentence id="783">
<word id="2357" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/>
<word id="2358" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/>
<word id="2359" head="2610" postag="p-s----n-" relation="ExD_AP" form="συ" lemma="συ"/>
</sentence>
Чтобы исправить это, я не могу просто .prettify его, потому что prettify переставляет атрибуты вернуться в алфавитный порядок. Вместо этого мне придется go подробнее узнать о подклассе XMLFormatter. Я надеюсь, что кто-то найдет это полезным в будущем!