繁体   English   中英

如何在条件下加入 XML 标签(Python)?

[英]How to join XML tags under condition (Python)?

我有一个结构如下的 XML 文件:

<?xml version="1.0" encoding="utf-8" ?>
    <pages>
    <page id="1" bbox="0.000,0.000,462.047,680.315" rotate="0">
    <textbox id="0" bbox="179.739,592.028,261.007,604.510">
    <textline bbox="179.739,592.028,261.007,604.510">
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">C</text>
    <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">A</text>
    <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">P</text>
    <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">I</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">T</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">O</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">L</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">O</text>
    <text> </text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
    <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
    <text>
    </text>
    </textline>
    </textbox>
</page>
</pages>

请注意,该文件比这大得多,并且它重复页面。 所以我有两种标签,字体和字体大小不同。 我想合并相同标签的字母,所以我想要一个 output 保持字体和字体大小,但也可以合并可以合并在一起的内容,例如:

<?xml version="1.0" encoding="utf-8" ?>
        <pages>
        <page id="1" bbox="0.000,0.000,462.047,680.315" rotate="0">
        <textbox id="0" bbox="179.739,592.028,261.007,604.510">
        <textline bbox="179.739,592.028,261.007,604.510">
        <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">C</text>
        <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">API</text>
        <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">TOLO III</text>
        </textline>
        </textbox>
    </page>
    </pages>

重要的是保持字母的原始顺序以及标签(所以我知道哪个是字体大小)。 所以到目前为止的代码如下所示:

import xml.etree.ElementTree as ET

MY_XML = ET.parse('fe.xml')

textlines = MY_XML.findall("./page/textbox/textline")

for textline in textlines:
    fulltext = []
    for text_elem in list(textline):
        # Get the text of each 'text' element and then remove it
        fulltext.append(text_elem.text)
        textline.remove(text_elem)

    # Create a new 'text' element and add the joined letters to it
    new_text_elem = ET.Element("text", font="NUMPTY+ImprintMTnum", ncolour="0", size="12.482")
    new_text_elem.text = "".join(fulltext).strip()

    # Append the new 'text' element to its parent
    textline.append(new_text_elem)

print(ET.tostring(MY_XML.getroot(), encoding="unicode"))

但它只适用于一个标签。 我想我需要设置一个条件,以便 for 循环检查所有标签,但我还没有找到有关如何执行此操作的 web 的信息。 如何包含其他标签? 非常感谢

为什么new_text_elem是具有固定属性的硬编码元素? 您不知道要分配哪些属性。

试试下面的。 创建另一个将所有标签写入字典的内部 for 循环。 您也可以迭代标签。

对于下一个元素,检查所有标签是否都在字典中以及它们是否相同。 阅读字典比较或仅遍历键并与==进行比较。

如果它们相同,则将该元素添加到您目前找到的相同元素列表中。 然后检查下一个元素。

如果它们不相同,则将列表的所有元素添加为新元素,并结合文本。 然后清除列表并重新开始。

概括:

  • 您遍历<text>元素。
  • 存储所有连续的<text>元素在列表中具有相同的标签。
  • 将它们一个接一个地存储在列表中可以保留顺序。
  • 一旦你遇到第一个不同的<text>元素,首先编写存储的元素,连接它们的文本,使用它们存储的标签和值。
  • 清除商店列表并重复。

以下是您需要实现的核心逻辑。

它不是端到端解决方案,但它处理核心逻辑。

import xml.etree.ElementTree as ET


xml = '''<?xml version="1.0" encoding="utf-8" ?>
<pages>
    <page id="1" bbox="0.000,0.000,462.047,680.315" rotate="0">
        <textbox id="0" bbox="179.739,592.028,261.007,604.510">
            <textline bbox="179.739,592.028,261.007,604.510">
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">C</text>
                <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">A</text>
                <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">P</text>
                <text font="NUMPTY+ImprintMTnum-it"  ncolour="0" size="12.333">I</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">T</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">O</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">L</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">O</text>
                <text> </text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
                <text font="NUMPTY+ImprintMTnum"  ncolour="0" size="12.482">I</text>
                <text>
                </text>
            </textline>
        </textbox>
    </page>
</pages>'''
words = []
root = ET.fromstring(xml)
pages = root.findall('.//page')
for page in pages:
    previous_key = None
    current_key = None
    texts = page.findall('.//text')
    for txt in texts:
        if previous_key:
            current_key = (txt.attrib.get('font',previous_key[0]),txt.attrib.get('size',previous_key[1]))
        else:
            current_key = (txt.attrib.get('font','empty'),txt.attrib.get('size','empty'))
        if current_key != previous_key:
            words.append([])
        words[-1].append(txt.text)
        previous_key = current_key

for group in words:
    if group:
        print(''.join(group))

output

C
API
TOLO III

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM