2016-03-22 4 views
1

Я пытаюсь использовать Python и BeautifulSoup 4 (bs4), чтобы преобразовать SVG Inkscape в XML-подобный формат для некоторых проприетарных программ. Кажется, я не могу заставить bs4 правильно разобрать минимальный пример. Мне нужен парсер, чтобы уважать самозакрывающиеся теги, обрабатывать unicode и не добавлять html-файлы. Я думал, что нужно указать парсер «lxml» с selfClosingTags, но это не так! проверьте это.Как заставить Python bs4 корректно работать с XML?

#!/usr/bin/python 
from __future__ import print_function 
from bs4 import BeautifulSoup 

print('\nbs4 mangled XML:') 
print(BeautifulSoup('<x><c name="b1"><d value="a"/></c></x>', 
    features = "lxml", 
    selfClosingTags = ('d')).prettify()) 

print('''\nExpected output: 
<x> 
<c name="b1"> 
    <d value="a"/> 
</c> 
</x>''') 

Печатается

bs4 mangled XML: 
/usr/local/lib/python2.7/dist-packages/beautifulsoup4-4.4.1-py2.7.egg/bs4/__init__.py:112: UserWarning: BS4 does not respect the selfClosingTags argument to the BeautifulSoup constructor. The tree builder is responsible for understanding self-closing tags. 
<html> 
<body> 
    <x> 
    <c name="b1"> 
    <d value="a"> 
    </d> 
    </c> 
    </x> 
</body> 
</html> 

Expected output: 
<x> 
<c name="b1"> 
    <d value="a"/> 
</c> 
</x> 

Я рассмотрел связанные вопросы StackOverflow, и я не найти решение.

This question адресует html-шаблон, но только для разбора подразделов html, а не для разбора xml.

This question относится к тому, чтобы получать beautifulsoup 4, чтобы уважать самозакрывающиеся теги и не имеет принятых ответов.

This question, кажется, указывает, что передача аргумента selfClosingTags должна помочь, но, как вы можете видеть, теперь это вызывает предупреждение BS4 does not respect the selfClosingTags argument, а самозакрывающиеся теги искажаются.

This question предполагает, что использование «xml» (не «lxml») приведет к автоматическому самоблокированию пустых тегов. Это может работать для моих целей, но применение анализатора «xml» к моим фактическим данным не выполняется, потому что файлы содержат юникод, который парсер «xml» не поддерживает.

Является ли «XML» отличается от «LXML», и это в стандарте, что «XML» не может поддержка юникода, и «LXML» не содержат самозакрывающиеся теги могут? Возможно, я просто пытаюсь сделать что-то, что запрещено?

+0

«, потому что файлы содержат юникод, которую" xml "парсер не поддерживает" → Нет, синтаксический анализатор XML * по определению * поддерживает Unicode. Вы должны опубликовать минимальный пример того, как вы открываете и записываете файлы. – roeland

+0

Почему бы не использовать сам lxml? –

ответ

1

Если вы хотите, чтобы результат выводился как xml, проанализируйте его как это. Данные xml могут содержать Юникод, однако, вы должны объявить кодировку:

#!/usr/bin/env python 
# -*- encoding: utf8 -*- 

The SelfClosingTags is no longer recognized. Вместо этого Beautiful Суп считает, что любой пустой тег является тегом с пустым элементом. Если вы добавите дочерний элемент в тег с пустым элементом, он перестанет быть тегом с пустыми элементами.

Изменение функции, чтобы посмотреть, как это должно работать (в дополнение к кодировке):

print(BeautifulSoup('<x><c name="b1"><d value="a®"/></c></x>', 
    features = "xml").prettify()) 

Результат:

<?xml version="1.0" encoding="utf-8"?> 
<x> 
<c name="b1"> 
    <d value="aÂŽ"/> 
</c> 
</x> 
+0

Ваше объявление кодирования объявляет кодировку исходного файла. Это не относится к вопросу. – roeland

+0

@roeland: Это актуально, поскольку без него любые символы Unicode в XML вызовут синтаксическую ошибку. 'Не-ASCII-символ: но не объявлено кодирование'; Http: // питона.org/dev/peps/pep-0263/ –

+0

Но OP загружает XML из SVG-файлов. – roeland