Как перебрать еще один узел в XML Python? - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть XML, структурированный так:

"""<?xml version="1.0" encoding="utf-8"?>
<pages>
    <page>
        <textbox>
            <new_line>
                <text size="12.482">C</text>
                <text size="12.333">A</text>
                <text size="12.333">P</text>
                <text size="12.333">I</text>
                <text size="12.482">T</text>
                <text size="12.482">O</text>
                <text size="12.482">L</text>
                <text size="12.482">O</text>
                <text></text>
                <text size="12.482">I</text>
                <text size="12.482">I</text>
                <text size="12.482">I</text>
                <text></text>
          </new_line>
        </textbox>
    </page>
</pages>
"""

Я перебираю текстовые элементы, которые являются потомками элемента new_line, чтобы объединить теги с тем же атрибутом size. Но я хочу указать, что элемент new_line должен находиться внутри элемента textbox. Поэтому я тоже хочу перебрать textbox. Я попытался добавить для l oop в моем коде, но это просто не работает. Вот код:

import lxml.etree as etree

parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('output22.xml', parser)
root = tree.getroot()

# Iterate over //newline block
for new_line_block in tree.xpath('//new_line'):
    # Find all "text" element in the new_line block
    list_text_elts = new_line_block.findall('text')

    # Iterate over all of them with the current and previous ones
    for previous_text, current_text in zip(list_text_elts[:-1], list_text_elts[1:]):
        # Get size elements
        prev_size = previous_text.attrib.get('size')
        curr_size = current_text.attrib.get('size')
        # If they are equals and not both null
        if curr_size == prev_size and curr_size is not None:
            # Get current and previous text
            pt = previous_text.text if previous_text.text is not None else ""
            ct = current_text.text if current_text.text is not None else ""
            # Add them to current element
            current_text.text = pt + ct
            # Remove preivous element
            previous_text.getparent().remove(previous_text)



newtree = etree.tostring(root, encoding='utf-8', pretty_print=True)
#newtree = newtree.decode("utf-8")
print(newtree)
with open("output2.xml", "wb") as f:
    f.write(newtree)

Мой ожидаемый вывод:

<pages>
    <page>
        <textbox>
            <new_line>
                <text size="12.482">C</text>
                <text size="12.333">API</text>
                <text size="12.482">TOLO</text>
                <text/>
                <text size="12.482">III</text>
                <text/>
            </new_line>
        </textbox>
    </page>
</pages>

Сейчас мой код не работает, потому что он соединяет один тег, а затем пропускает следующий, я думаю, что нет указание textbox является проблемой.

1 Ответ

0 голосов
/ 29 апреля 2020

Хотя ваш вопрос похож на предыдущий, на этот раз проблема более простая и понятная. Вы можете сначала извлечь данные, а затем записать их в нужный формат. Вот пример.

из упрощенного импорта импорта SimplifiedDo c, req, utils xml = "" "

<pages>
    <page>
        <textbox>
            <new_line>
                <text size="12.482">C</text>
                <text size="12.333">A</text>
                <text size="12.333">P</text>
                <text size="12.333">I</text>
                <text size="12.482">T</text>
                <text size="12.482">O</text>
                <text size="12.482">L</text>
                <text size="12.482">O</text>
                <text></text>
                <text size="12.482">I</text>
                <text size="12.482">I</text>
                <text size="12.482">I</text>
                <text></text>
          </new_line>
        </textbox>
    </page>
</pages>
"""
doc = SimplifiedDoc(xml)
new_line = doc.new_line
lastSize = None
lst = []
texts = ""
for t in new_line.texts:
    if not lastSize or t.size==lastSize:
        texts += t.text
        lastSize = t.size
    else:
        lst.append((lastSize,texts))
        texts = t.text
        if t.size:
            lastSize = t.size
        else: 
            lst.append("<text />")
            lastSize=None
print(lst)

Результат:

[('12.482', 'C'), ('12.333', 'API'), ('12.482', 'TOLO'), '<text />', ('12.482', 'III'), '<text />']
...