亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

鴻蒙傳說 2022-06-28 16:47:19
目前我正在研究一個語料庫/數據集。它是 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 文件中的圖片如下所示:XML文件的文本版本: 點擊這里示例/預期輸出圖像(下):到目前為止我所做的編碼:for i in range(len(List_of_root_nodes)):true_false = Truecurrent = List_of_root_nodes[i]start_ID = current.PDante_ID#print('start:', start_ID)  # For Testingend_ID = Nonenumber = str(i+1)  # This number will serve as i used with SD and ED that is (SDi and EDi)discourse_starting_symbol = "SD" + numberdiscourse_ending_symbol = "ED" + numberwhile 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 = Nonene_id = Nonefor 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
查看完整描述

2 回答

?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

像這樣(a.xml 是您上傳的 XML):


請注意,代碼沒有使用任何外部庫。


import xml.etree.ElementTree as ET


SD = 'SD'

ED = 'ED'


root = ET.parse('a.xml')


counter = 1


for 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 += 1

ET.dump(root)


查看完整回答
反對 回復 2022-06-28
?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

每當您需要修改具有各種細微差別的 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">

  <xsl:output indent="yes"/>

  <xsl:strip-space elements="*"/>


  <!-- IDENTITY TRANSFORM -->    

  <xsl:template match="@*|node()">

    <xsl:copy>

      <xsl:apply-templates select="@*|node()"/>

    </xsl:copy>

  </xsl:template>


  <!-- EDIT FIRST W NODE -->    

  <xsl:template match="W[count(preceding::W)=0]">

    <xsl:copy>

      <xsl:copy-of select="@*"/>

      <xsl:value-of select="concat('SDI ', text())"/>

    </xsl:copy>

  </xsl:template>


  <!-- EDIT LAST W NODE -->    

  <xsl:template match="W[count(preceding::W)+1 = count(//W)]">

    <xsl:copy>

      <xsl:copy-of select="@*"/>

      <xsl:value-of select="concat('EDI ', text())"/>

    </xsl:copy>

  </xsl:template>


</xsl:stylesheet>

Python (無循環或 if/else 邏輯)


import lxml.etree as et


doc = et.parse('/path/to/Input.xml')

xsl = et.parse('/path/to/Script.xsl')


# CONFIGURE TRANSFORMER

transform = et.XSLT(xsl)    


# TRANSFORM SOURCE DOC

result = transform(doc)


# OUTPUT TO CONSOLE

print(result)


# SAVE TO FILE

with open('Output.xml', 'wb') as f:

    f.write(result)


查看完整回答
反對 回復 2022-06-28
  • 2 回答
  • 0 關注
  • 197 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號