2 回答

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)

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)
添加回答
舉報