BeautifulSoup не читает теги должным образом

Я пытаюсь проанализировать xml с помощью BeautifulSOup, но это приводит к неправильному выводу.

файл.xml:

<?xml version="1.0" ?> 
<opening name="value1" >
      <element name="value1.1"/>
      <element name="value1.2">
        <element name="1.2.1"/>
      </element>
      <element name="value1.3">
        <element name="value1.3.1"/>
      </element>
</opening>

используя следующий код:

>>> a=open('file.xml').read()
>>> import BeautifulSoup
>>> s= BeautifulSoup.BeautifulSoup(a)
>>> print s.prettify()

и я получаю следующий вывод:

<?xml version='1.0' encoding='utf-8'?>
<opening name="value1">
 <element name="value1.1">
 </element>
 <element name="value1.2">
 </element>
 <element name="1.2.1">
 </element>
 <element name="value1.3">
 </element>
 <element name="value1.3.1">
 </element>
</opening>

Почему все элементы отображаются как дочерние от открывающего тега? Как правильно разобрать этот файл?

Я также пытался использовать s= BeautifulSoup.BeautifulStoneSoup(a), но это тоже не сработало.


person Archit Jain    schedule 13.08.2012    source источник
comment
Я подтвердил вашу проблему с BeautifulSoup3. Похоже, проблема исправлена ​​в BeautifulSoup4. Установите BeautifulSoup4.   -  person Steven Rumbalski    schedule 14.08.2012
comment
BeautifulSoup4 работал на меня. Спасибо @StevenRumbalski   -  person Archit Jain    schedule 05.01.2013


Ответы (2)


BeautifulSoup в первую очередь является HTML синтаксическим анализатором, который изо всех сил старается справиться с искаженным HTML. Существуют XML-библиотеки, такие как lxml, которые я настоятельно рекомендую — попробуйте.

Пример:

import lxml.etree

xml = """<?xml version="1.0" ?> 
<opening name="value1" >
      <element name="value1.1"/>
      <element name="value1.2">
        <element name="1.2.1"/>
      </element>
      <element name="value1.3">
        <element name="value1.3.1"/>
      </element>
</opening>
"""

r = lxml.etree.fromstring(xml)
r.xpath('//element/@name')
# ['value1.1', 'value1.2', '1.2.1', 'value1.3', 'value1.3.1']
person Jon Clements♦    schedule 13.08.2012
comment
Если вам по-прежнему нужны функции, предоставляемые BeautifulSoup, вы можете просто указать, что вместо этого он использует синтаксический анализатор xml, т.е. BeautifulSoup(markup, "xml") -- для этого требуется lxml. - person Dunes; 14.08.2012

Beautiful Soup 3 требует специального аргумента для корректного закрытия тегов. Вам нужен аргумент selfClosingTags для конструктора BeautifulStoneSoup. Используйте что-то вроде:

soup = BeautifulStoneSoup(markup, selfClosingTags=['element'])
person Aaron DeVore    schedule 23.08.2012