使用Python的elementtree为带有文本的节点进行Bookending

时间:2015-03-10 03:09:44

标签: python xml elementtree minidom

我试图将文本书挡添加到XML文件中的字符串。如果之前已经翻译过字符串,我想在字符串的开头和结尾添加@@@###以进行进一步处理。最终结果如下:

<group>
    <seg-source>
        <mrk mid="1" mtype="seg">I have a <g id="157">red</g> pen.</mrk>
    </seg-source>
    <target>
        <mrk mid="1" mtype="seg">@@@J'ai un stylo <g id="157">rouge</g>.###</mrk>
    </target>
</group>

我在使用xml.minidom之前尝试过并创建了一个通用文本节点,例如start_tag = xmldoc.createTextNode(u'@@@'),并且能够将节点作为子节点插入/追加。 (出于各种原因,我最终放弃使用minidom。)

我能够很快将我的脚本从minidom转换为elementtree,但我却陷入了这个最关键的问题。我已阅读并重新阅读文档但我无法找到任何特定于我需要做的事情,特别是因为很多<mrk>元素都有子元素,例如<g>示例中的标记。此外,有时<mrk>节点中的第一件事可能不是文本元素,因此我无法替换文本。

Python代码是非常基本的,正如你所看到的,我有把手放在书挡上。

for target in group.iter('target'):
    for mrk in target.iter('mrk'):

        # Adding "@@@" at front of <mrk>
        mrk.insert(0, <magical text-only element here>)

        # Adding "###" to end of <mrk>
        mrk.append(<magical text-only element here>)

非常感谢!

1 个答案:

答案 0 :(得分:2)

ElementTree以非XML方式处理文本。这里涉及几个技巧。第一个是在<a>xxx<b>yyy</b>zzz<c>eee</c>rrr</a>,你进入&#34; zzz&#34;是通过tail元素的<b>。 (我知道,XSLT专家们正在咬牙切齿。)

另一个使用的技巧是您可以将ET元素视为子节点列表。因此,您可以使用len(root)来获取它拥有的子项数(忽略文本节点)。

这是一个快速示例程序,似乎在我尝试时运行。您可能希望根据自己的需要调整它,但它应该让您前进。

import xml.etree.ElementTree as ET

xmlin="""
    <group>
        <mrk>I have a red pen.</mrk>
        <mrk>I have a <g id="157">red</g> pen.</mrk>
        <mrk><xyzzy>Hey!</xyzzy> I have a <g>red</g> pen.</mrk>
        <mrk>There is text <and>this</and></mrk>
    </group>
"""

root = ET.fromstring(xmlin)

for mrk in root:
    if (mrk.text == None):
        mrk.text = "@@@"
    else:
        mrk.text = "@@@" + mrk.text

    # do we have children?
    if (len(mrk) == 0):
        mrk.text = mrk.text + "###"
    else:
        last = mrk[len(mrk)-1]
        if (last.tail == None):
            last.tail = "###"
        else:
            last.tail = last.tail + "###"

print('ET.tostring(root)')
print ET.tostring(root)