Я пытаюсь вставить родительский элемент (new_line
) в файл XML, если существует определенное расстояние между значениями атрибутов узла и его предыдущего элемента. Например:
<pages>
<page>
<textbox>
<textline>
<new_line>
<text> a </text>
<text> b </text>
</new_line>
<new_line>
<text> c </text>
</new_line>
</textline>
<textline>
<new_line>
<text> d </text>
</new_line>
</textbox>
<textbox>
<textline>
<new_line>
<text> e </text>
<text> f </text>
</new_line>
</textline>
</textbox>
</page>
</pages>
Однако это не работает должным образом, так как независимо от расстояния он берет последний элемент text
и вставляет его в следующий элемент new_line
, даже если он не должно.
Примерно так:
<pages>
<page>
<textbox>
<textline>
<new_line>
<text> a </text>
<text> b </text>
</new_line>
</textline>
<textline>
<new_line>
<text> c </text>
<text> d </text>
</new_line>
</textbox>
<textbox>
<textline>
<new_line>
<text> e </text>
<text> f </text>
</new_line>
</textline>
</textbox>
</page>
</pages>
Что может быть не так в моем коде?
import lxml.etree as etree
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('fe3.xml', parser)
root = tree.getroot()
# Get the first BBox value as float
# Return null if not found
def getBBoxFirstValue(line):
if line is not None:
bb = line.attrib.get('bbox')
if bb is not None:
try:
return float(bb.split(",")[0])
except ValueError:
pass
return None
new_line = None
previous_bb = None
for x in tree.xpath('//text'):
# Get current bb value
bb = getBBoxFirstValue(x)
# Check current and past values aren't empty
if bb is not None and previous_bb is not None:
#print(bb, previous_bb, (bb-previous_bb))
#print(abs(bb-previous_bb))
# If distance with preview bb > 10
if (bb - previous_bb) > 20 or -50 <= (bb - previous_bb) <= -300:
# If new_line isn't empty: it's inserted into parent tag at position of current tag
if new_line is not None:
x.getparent().insert(x.getparent().index(x), new_line)
# A new "new_line" element is created
new_line = etree.Element("new_line")
# If the new line isn't not (e.g. one distance > 10 has been already found)
if new_line is not None:
new_line.append(x)
# Keep latest non empty BBox 1st value
if bb is not None:
previous_bb = bb
# Add last new_line element if not null
if new_line is not None:
tree.xpath('//text')[-1].getparent().append(new_line)
newtree = etree.tostring(root, encoding='utf-8', pretty_print=True)
#newtree = newtree.decode("UTF-8")
print(newtree)
with open("outputprova.xml", "wb") as f:
f.write(newtree)
Входной файл: ссылка
Выходной файл: ссылка