У меня есть элемент XML, который выглядит так:

< Сильный > XML

<page>
    <textline id="1">
        <text>C</text>
        <text>o</text>
        <text>n</text>
        <text>t</text>
        <text>a</text>
        <text>k</text>
        <text>t</text>
    </textline>
    <textline id="2">
        <text>
        </text>
    </textline>
    <textline id="3">
        <text>M</text>
        <text>e</text>
    </textline>
</page>

Я пытаюсь получить все теги <textline> только :

with open(path_to_xml_file) as xml_file:    
     parsed_xml = BeautifulSoup(xml_file, 'xml')
     text_lines = parsed_xml.find_all("textline")

Однако text_lines включает в себя все дочерние элементы <textline> - это означает, что он включает все теги <text></text>.

Я не могу найти ничего в документации, которая объясняет, как выбрать только фактический тег (а не дочерние элементы, дочерние элементы и т. Д.).

Я нашел параметр recursive=False, который должен выбирать только дочерних элементов direct , поэтому я решил применить это к тегу page:

text_lines = parsed_xml.find_all("page", recursive=False)

Но это возвращает пустой список: []

Ожидаемый результат:

<textline id="1"></textline>
<textline id="2"></textline>
<textline id="3"></textline>
1
oliverbj 27 Июн 2019 в 10:14

3 ответа

Лучший ответ

Вы можете установить string=''

< Сильный > Пример:

xml = """<page>
<textline id="1">
  <text>C</text>
  <text>o</text>
  <text>n</text>
  <text>t</text>
  <text>a</text>
  <text>k</text>
  <text>t</text>
</textline>
<textline id="2">
  <text>
  </text>
</textline>
<textline id="3">
  <text>M</text>
  <text>e</text>
</textline>
</page>"""

from bs4 import BeautifulSoup
parsed_xml = BeautifulSoup(xml, 'xml')
text_lines = []
for tag in parsed_xml.find_all("textline"):
    tag.string = ''
    text_lines.append(tag)
print(text_lines)

< Сильный > Вывод :

[<textline id="1"></textline>,
 <textline id="2"></textline>,
 <textline id="3"></textline>]
2
Rakesh 27 Июн 2019 в 07:43

Я знаю, что изначально пометил этот вопрос beautifulsoup, но я просто хотел поделиться тем, что я фактически использовал. Решение от @Rakesh работает с beaufitulsoup.

Я фактически использовал встроенный анализатор XML Pythons:

import xml.etree.ElementTree as ET

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

for textline in root.iter('textline'):
    print(textline)

Я думаю, что это намного более чистое решение - так что, надеюсь, это поможет любому, кто встретит этот пост.

0
oliverbj 27 Июн 2019 в 08:09

Вы можете использовать метод clear () , чтобы удалить все внутренние теги <text> из тегов <textline>,

Еще одна вещь, которую вы не можете отправить имя файла в BeautifulSoup , вы должны открыть его и отправить содержимое, здесь я сохранил содержимое XML в переменной.

myxml = """<page>
<textline id="1">
  <text>C</text>
  <text>o</text>
  <text>n</text>
  <text>t</text>
  <text>a</text>
  <text>k</text>
  <text>t</text>
</textline>
<textline id="2">
  <text>
  </text>
</textline>
<textline id="3">
  <text>M</text>
  <text>e</text>
</textline>
</page>"""

parsed_xml = BeautifulSoup(myxml, 'xml')
text_lines = parsed_xml.find_all("textline")
for tl in text_lines:
    tl.clear()

print(text_lines)

< Сильный > Вывод :

[<textline id="1"/>, <textline id="2"/>, <textline id="3"/>]
1
Murali 27 Июн 2019 в 08:05