【问题标题】:Element Tree is not modifying element text元素树没有修改元素文本
【发布时间】:2021-11-09 06:47:10
【问题描述】:

我正在使用 ElementTree 修改 xliff 文件,其中包含 Excel 工作表中包含的文本。我想运行整个文件并确定我在 Excel 工作表中匹配的元素(匹配基于包含在“mid”属性值中的段 id)。找到匹配项后,我想用从 Excel 工作表中提取的文本填充元素。对于此示例,我使用虚拟文本“Target Segment{segment id}”

我的代码做我想做的一切。我可以识别每个元素并根据需要提取元素文本和属性。我设置了元素的文本值,可以看到打印结果前后的差异 - 之前的“mrk.text”为无,设置新值后,“mrk.text”填充了正确的虚拟文本.所以看起来一切正常。

但是 - 当我生成 xml 文件时,我可以看到元素文本仍然是空的。同时,我对 xml 所做的其他修改——例如注册命名空间和包含 xml 声明都可以正常工作)。

我希望文本出现在“目标”元素的子元素“mrk”元素中。但是那里没有写任何东西。

我不确定自己做错了什么。

我已阅读 python.org 上的 xml.etree.ElementTree 文档,并在此站点和其他几个站点上搜索了正确答案。我找到了暗示可能的解决方案的答案,但没有什么能完全做到这一点。

(我知道我的标签引用可以在不显式调用命名空间 URI 的情况下进行,但我是 Element Tree 的新手,想在改进我的代码之前先解决我的问题)

我要修改的 XML 示例在这里:

        <trans-unit id="f60d234c-2d06-47e7-b4aa-e2c7a7caf0e8">
            <source>Please select all that apply.</source>
            <seg-source>
                <mrk mtype="seg"
                     mid="1751">Please select all that apply.</mrk>
            </seg-source>
            <target>
                <mrk mtype="seg"
                     mid="1751"/>
            </target>
        </trans-unit>

相关python代码在这里:

beolroot = ET.parse(filetobeol).getroot()
for tu in beolroot.findall(".//{urn:oasis:names:tc:xliff:document:1.2}trans-unit"):
    ET.register_namespace("sdl", "http://sdl.com/FileTypes/SdlXliff/1.0")
    ET.register_namespace("", "urn:oasis:names:tc:xliff:document:1.2")
    #print (tu)
    srctxt = tu.find("./{urn:oasis:names:tc:xliff:document:1.2}source")
    trg = tu.find("./{urn:oasis:names:tc:xliff:document:1.2}target")
    #print (srctxt)
    print (srctxt.text)
    #print (trg)
    for target in tu.findall("./{urn:oasis:names:tc:xliff:document:1.2}target"):
        for mrk in target.findall("./{urn:oasis:names:tc:xliff:document:1.2}mrk"):
            print ("mrk is element id " + str(mrk))
            print ("mrk text is: " +str(mrk.text))
            mid = mrk.get("mid")
            print ("segment id is: " +str(mid))
            if mid in srctrgmap.keys():
                mrk = target.find("./{urn:oasis:names:tc:xliff:document:1.2}mrk")
                targetvalue = srctrgmap[mid]
                #print(targetvalue)
                mrk.text = str(targetvalue)
                target.text = str(targetvalue)
                print ("mrk is STILL element id: " + str(mrk))
                print ("new mrk text is: " +str(mrk.text))
                print ("new target  text is: " +str(target.text))
            else:
                print("Segment Number " + str(mid) + " has no translation target text")
tree.write("output.sdlxliff", encoding="utf-8", xml_declaration=True)

【问题讨论】:

  • 涉及命名空间,但问题中的 XML 示例没有命名空间。这将使提供帮助变得更加困难。请参阅minimal reproducible example。
  • srctrgmap 定义在哪里?
  • 谢谢。我将添加更多 xml 示例以显示名称空间。 srctrgmap 是在另一个读取 excel 文件的代码块中定义的。目前它只是一个字典,以段 id 数字作为键,一些填充文本作为值,所以它包含很多像这样的条目 {1786 : 'TargetSegment1786,... '}
  • 好的。但我希望你能看到minimal reproducible example 的意义。我应该能够在不更改任何内容的情况下复制、粘贴和运行问题中的代码。目前这是不可能的。
  • 感谢@mzjn 对此的帮助。您提出的生成最小可重复示例的建议使我解决了问题。这是我在这里的第一篇文章。以后我不会忘记做的。

标签: python xml elementtree xliff


【解决方案1】:

以下代码有效。正如建议的那样,我研究了一个最小的可重现示例。在这样做的过程中,我制作了一个有效的版本。我不确定出了什么问题。但是这段代码现在完成了我需要它做的事情。

此处为xml示例:

    <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:sdl="http://sdl.com/FileTypes/SdlXliff/1.0"
       xmlns="urn:oasis:names:tc:xliff:document:1.2"
       version="1.2"
       sdl:version="1.0">
    <file original="C:\File\Location\example.xml">
        <body>
            <trans-unit id="a">
                <source>Foo</source>
                <seg-source>
                    <mrk mtype="seg"
                         mid="1328">Foo</mrk>
                </seg-source>
                <target>
                    <mrk mtype="seg"
                         mid="1328"/>
                </target>
                <sdl:seg-defs>Bar</sdl:seg-defs>
            </trans-unit>
            <trans-unit id="b">
                <source>My Hovercraft</source>
                <seg-source>
                    <mrk mtype="seg"
                         mid="1329">My Hovercraft</mrk>
                </seg-source>
                <target>
                    <mrk mtype="seg"
                         mid="1329"/>
                </target>
                <sdl:seg-defs>Is full of eels</sdl:seg-defs>
            </trans-unit>
            <trans-unit id="c">
                <source>I will not buy this record</source>
                <seg-source>
                    <mrk mtype="seg"
                         mid="1330">I will not buy this record</mrk>
                </seg-source>
                <target>
                    <mrk mtype="seg"
                         mid="1330"/>
                </target>
                <sdl:seg-defs>It is scratched</sdl:seg-defs>
            </trans-unit>
            <trans-unit id="d">
                <source>I will not buy this tobacconist</source>
                <seg-source>
                    <mrk mtype="seg"
                         mid="1331">I will not buy this tobacconist</mrk>
                </seg-source>
                <target>
                    <mrk mtype="seg"
                         mid="1331"/>
                </target>
            <sdl:seg-defs>It is scratched</sdl:seg-defs>
            </trans-unit>
            <trans-unit id="f">
                <source>I want to buy</source>
                <seg-source>
                    <mrk mtype="seg"
                         mid="1332">I want to buy</mrk>
                </seg-source>
                <target>
                    <mrk mtype="seg"
                         mid="1332"/>
                </target>
                <sdl:seg-defs>Some Matches</sdl:seg-defs>
            </trans-unit>
        </body>
    </file>
</xliff>

在这里工作的python:

import xml.etree.ElementTree as ET

filetobeol = 'D:\\Stack\\example.xml'

srctrgmap = {'1328': 'Target Segment1328',
             '1330': 'Target Segment1330',
             '1332': 'Target Segment1332'
             }

tree = ET.parse(filetobeol)
beolroot = tree.getroot()
for tu in beolroot.findall(".//{urn:oasis:names:tc:xliff:document:1.2}trans-unit"):       
    ET.register_namespace("sdl", "http://sdl.com/FileTypes/SdlXliff/1.0")
    ET.register_namespace("", "urn:oasis:names:tc:xliff:document:1.2")
    for target in tu.findall("./{urn:oasis:names:tc:xliff:document:1.2}target"):
        for mrk in target.findall("./{urn:oasis:names:tc:xliff:document:1.2}mrk"):
            print ("mrk is element id " + str(mrk))
            print ("mrk text is: " +str(mrk.text))
            mid = mrk.get("mid")
            print ("segment id is: " +str(mid))
            if mid in srctrgmap.keys():
                stillmrk = target.find("./{urn:oasis:names:tc:xliff:document:1.2}mrk")
                targetvalue = srctrgmap[mid]
                #print(targetvalue)
                stillmrk.text = str(targetvalue)
                print ("mrk is STILL element id: " + str(stillmrk))
                print ("new mrk text is: " +str(stillmrk.text))
            else:
                print("Segment Number " + str(mid) + " has no translation target text")
tree.write("D:\\Stack\\outexample.xml", encoding="utf-8", xml_declaration=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2018-11-07
    • 2023-03-18
    • 2021-11-30
    • 2015-03-09
    • 2016-02-29
    • 1970-01-01
    相关资源
    最近更新 更多