如何使用 lxml 更改不同的层次结构标签?

How to change different hierarchy tags with lxml?

我想使用 python 中的 lxml 将所有标签名称 <p> 更改为 <PARAGRAPH>。问题是我可以更改外部概念标签的 <p> 标签和第一个内部概念 <p> 标签,但我不知道如何更改所有剩余的 <p> 标签。

这是 xml 文件的示例。

<dita>
    <topic id="id15CDB0PL09E">
        <title id="id15CDB0R0VYB"><?FM MARKER [Header/Footer ] All?>Control
        </title>
        <shortdesc>CONTROL</shortdesc>
        <concept id="id15CDB0Q0Q4G">
            <title id="id15CDB0R0VHA">General
            </title>
            <conbody>
                <p>This section
                </p>
            </conbody>
            <concept id="id156F7H00GIE">
                <title id="id15CDB0R0V1W">System
                </title>
                <conbody>
                    <p>Engine  
                    </p>
                    <p>The ECU 
                    </p>
                    <p>The aircraft 
                    </p>
                    <p>The system
                    </p>
               </conbody>
            </concept>
        </concept>
    </topic>
</dita>

这是我使用 lxml 的 python 代码。

# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

from lxml import etree
doc = etree.parse("73-20.xml")

#Lista para guardar las tag que son hijas de la tag concept
conceptDentro=[]
conbodysFuera=[]
conbodysDentro=[]

#Consigue la root tag (en este caso es dita y su unico hijo es topic)
raiz = doc.getroot()
print(raiz.tag)
print("\n")

#Encuentra todos los tag concept que son hijos de la tag topic
conceptAfuera = raiz[0].findall("concept")
print(conceptAfuera)
print("\n")


#Con este ciclo encuentra las tag concept que son hijas de la tags conceptAfuera
for i in range(len(conceptAfuera)):
    #conbodysFuera son los tag conbody que son hijos de los conceptAfuera, en este caso solo hay 1
    conbodysFuera.extend(conceptAfuera[i].findall("conbody"))
    #conceptDentro son las tags concept dentro de las tag conceptAfuera
    conceptDentro.extend(conceptAfuera[i].findall("concept"))

#ConceptDentro es una lista que almacena todas las tag concept dentro de las tag conceptAfuera    
print("Etiquetas de conceptDentro: ",conceptDentro) 
print("\n")
print("Etiquetas de conbodysFuera: ",conbodysFuera)
print("\n")

#Ciclo para encontrar todas las tag conbody dentro de los conceptDentro
for i in range(len(conceptDentro)):
    conbodysDentro.extend(conceptDentro[i].findall("conbody"))

print("Etiquetas de conbodysDentro: ", conbodysDentro)
print("\n")

#Ciclo para cambiar la tag p de conbodysFuera
for i in range(len(conbodysFuera)):
    for j in range(len(conbodysFuera[i].findall("p"))):
        conbodysFuera[i].findall("p")[j].tag="PARAGRAPH"
        
#Ciclo para cambiar la tag p de conbodysDentro
for i in range(len(conbodysDentro)):
    #for j in range(len(conbodysDentro[i].findall("p"))):
        conbodysDentro[i].findall("p")[j].tag="PARAGRAPH"

#print(etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8"))
doc.write("FerNewtags.xml")

如您所见,Ciclo 的最后一个被写为注释,因为它会导致 IndexError: list index out of range

有什么想法吗?

我认为你过于复杂了。只需找到所有 p 元素(带有 .xpath().findall())并更改 .tag 属性...

的值
from lxml import etree

tree = etree.parse("73-20.xml")

for p in tree.findall(".//p"):
    p.tag = "paragraph"

tree.write("FerNewtags.xml")

输出 (FerNewtags.xml)

<dita>
    <topic id="id15CDB0PL09E">
        <title id="id15CDB0R0VYB"><?FM MARKER [Header/Footer ] All?>Control
        </title>
        <shortdesc>CONTROL</shortdesc>
        <concept id="id15CDB0Q0Q4G">
            <title id="id15CDB0R0VHA">General
            </title>
            <conbody>
                <paragraph>This section
                </paragraph>
            </conbody>
            <concept id="id156F7H00GIE">
                <title id="id15CDB0R0V1W">System
                </title>
                <conbody>
                    <paragraph>Engine
                    </paragraph>
                    <paragraph>The ECU
                    </paragraph>
                    <paragraph>The aircraft
                    </paragraph>
                    <paragraph>The system
                    </paragraph>
               </conbody>
            </concept>
        </concept>
    </topic>
</dita>