如何使用python修改xml文件中嵌套元素的文本?

目前我正在研究一个语料库/数据集。它是 xml 格式,如下图所示。我面临一个问题。我想一一访问所有'ne'元素,如下图所示。然后我想访问'ne'元素内的'W'元素的文本。然后我想将你的符号'SDi'和'EDi'与这些'W'元素的文本连接起来。'i' 可以取从 1 开始的任何正整数。在 'SDi' 的情况下,我只需要在 'ne' 元素内的第一个 'W' 元素的文本。在“EDi”的情况下,我只需要最后一个“W”元素的文本那是在'ne'元素内。目前我在运行代码后没有得到任何输出。我认为这是因为元素“W”从未被访问过。此外,我认为元素'W'未被访问,因为它是元素'ne'的孙子,因此它不能直接访问,而是在其父节点的帮助下可能是可能的。

注1:“ne”元素中子元素的个数和名称不相同。

注2:这里只说明需要的东西。您可能会在编码/图片中找到一些其他细节,但忽略它们。

我正在使用 Spyder (python 3.6) 任何帮助将不胜感激。

我正在处理的 XML 文件中的图片如下所示:

http://img4.mukewang.com/62bac03200013cbb09550602.jpg

XML文件的文本版本: 点击这里

示例/预期输出图像(下):

http://img3.mukewang.com/62bac0410001c55f09500551.jpg

到目前为止我所做的编码:


for i in range(len(List_of_root_nodes)):

true_false = True

current = List_of_root_nodes[i]

start_ID = current.PDante_ID

#print('start:', start_ID)  # For Testing

end_ID = None

number = str(i+1)  # This number will serve as i used with SD and ED that is (SDi and EDi)


discourse_starting_symbol = "SD" + number

discourse_ending_symbol = "ED" + number


while true_false:    

    if current.right_child is None:        

        end_ID = current.PDante_ID

        #print('end:', end_ID)  # For Testing

        true_false = False        

    else:        

        current = current.right_child


# Finding 'ne' element with id='start_ID'

ne_text = None

ne_id = None


for ne in myroot.iter('ne'):    

    ne_id = ne.get('id')


    # If ne_id matches with start_ID means the place where SDi is to be placed is found    

    if ne_id == start_ID:        

        for w in ne.iter('W'):            

            ne_text = str(w.text)            

            boundary_and_text = " " + str(discourse_starting_symbol) + " " + ne_text

            w.text = boundary_and_text

            break


鸿蒙传说
浏览 166回答 2
2回答

慕标5832272

像这样(a.xml 是您上传的 XML):请注意,代码没有使用任何外部库。import xml.etree.ElementTree as ETSD = 'SD'ED = 'ED'root = ET.parse('a.xml')counter = 1for ne in root.findall('.//ne'):    w_lst = ne.findall('.//W')    if w_lst:        w_lst[0].text = '{}{} {}'.format(SD, counter, w_lst[0].text)        if len(w_lst) > 1:            w_lst[-1].text = '{} {}{}'.format(w_lst[-1].text, ED, counter)        counter += 1ET.dump(root)

元芳怎么了

每当您需要修改具有各种细微差别的 XML 时,请考虑XSLT,这是一种专门用于转换 XML 文件的语言。您可以使用 Python 的第三方模块lxml(不是内置的etree)运行 XSLT 1.0 脚本。具体来说,调用身份转换以按原样复制 XML,然后运行两个模板以添加SDI到第一个<W>和最后一个 EDI 的文本到最后一个文本<W>。如果有 10 或 10,000 个<W>节点,无论是否深度嵌套,解决方案都会起作用。要演示 StackOverflow 的顶级 Python 和 XSLT 用户的示例数据,请参阅在线演示,其中SDI和EDI添加到第一个和最后一个<user>节点:XSLT (另存为 .xsl 文件,在 Python 中加载的特殊 .xml 文件)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">&nbsp; <xsl:output indent="yes"/>&nbsp; <xsl:strip-space elements="*"/>&nbsp; <!-- IDENTITY TRANSFORM -->&nbsp; &nbsp;&nbsp;&nbsp; <xsl:template match="@*|node()">&nbsp; &nbsp; <xsl:copy>&nbsp; &nbsp; &nbsp; <xsl:apply-templates select="@*|node()"/>&nbsp; &nbsp; </xsl:copy>&nbsp; </xsl:template>&nbsp; <!-- EDIT FIRST W NODE -->&nbsp; &nbsp;&nbsp;&nbsp; <xsl:template match="W[count(preceding::W)=0]">&nbsp; &nbsp; <xsl:copy>&nbsp; &nbsp; &nbsp; <xsl:copy-of select="@*"/>&nbsp; &nbsp; &nbsp; <xsl:value-of select="concat('SDI ', text())"/>&nbsp; &nbsp; </xsl:copy>&nbsp; </xsl:template>&nbsp; <!-- EDIT LAST W NODE -->&nbsp; &nbsp;&nbsp;&nbsp; <xsl:template match="W[count(preceding::W)+1 = count(//W)]">&nbsp; &nbsp; <xsl:copy>&nbsp; &nbsp; &nbsp; <xsl:copy-of select="@*"/>&nbsp; &nbsp; &nbsp; <xsl:value-of select="concat('EDI ', text())"/>&nbsp; &nbsp; </xsl:copy>&nbsp; </xsl:template></xsl:stylesheet>Python (无循环或 if/else 逻辑)import lxml.etree as etdoc = et.parse('/path/to/Input.xml')xsl = et.parse('/path/to/Script.xsl')# CONFIGURE TRANSFORMERtransform = et.XSLT(xsl)&nbsp; &nbsp;&nbsp;# TRANSFORM SOURCE DOCresult = transform(doc)# OUTPUT TO CONSOLEprint(result)# SAVE TO FILEwith open('Output.xml', 'wb') as f:&nbsp; &nbsp; f.write(result)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python