如何向lxml解析的XML Element对象添加多个同层级同标签元素
解决lxml objectify批量添加同层级元素的问题
你遇到的核心问题很明确:同一个XML元素对象不能同时存在于树的多个位置。当你两次调用insert()传入同一个installation对象时,第二次操作其实是把这个元素从第一个位置移动到了第二个位置,而不是创建新的元素副本,所以最终只会看到一个
解决方案:每次创建新元素或复制现有元素
下面提供两种可行的实现方式,你可以根据需求选择:
方法1:循环创建新的元素对象
如果需要批量添加相同结构的元素,最直接的方式是在循环中每次调用objectify.fromstring()生成新的元素实例:
from lxml import etree from lxml import objectify # 读取XML文件 file_path = 'C:/Users/gustu/Dropbox/RATP2/uploadANFR/ANFRAutoXML/3 - Mise à jour schéma echange ANFR/Schema_Echanges_MCR/anfr_laboratoire/aideInternet/extract.xml' with open(file_path, 'r') as fileobject: tree = objectify.parse(fileobject) root = tree.getroot() # 定义installation元素的模板字符串 install_template = "<installation hauteur=\"8\" distance=\"9\"><type></type></installation>" # 批量添加任意数量的元素(示例添加3个) for _ in range(3): # 每次生成新的Element对象 new_install = objectify.fromstring(install_template) # 使用append直接添加到末尾,或者用insert指定位置 root.mesure.installationsVisibles.append(new_install) # 输出格式化后的XML print(etree.tostring(root, pretty_print=True).decode('utf-8'))
方法2:复制已有的元素对象
如果已经有一个基础元素,想要基于它复制并修改属性(比如不同的hauteur或distance),可以使用etree.Element.copy()来创建元素副本:
from lxml import etree from lxml import objectify file_path = 'C:/Users/gustu/Dropbox/RATP2/uploadANFR/ANFRAutoXML/3 - Mise à jour schéma echange ANFR/Schema_Echanges_MCR/anfr_laboratoire/aideInternet/extract.xml' with open(file_path, 'r') as fileobject: tree = objectify.parse(fileobject) root = tree.getroot() # 创建第一个installation元素 base_install = objectify.fromstring("<installation hauteur=\"8\" distance=\"9\"><type></type></installation>") root.mesure.installationsVisibles.append(base_install) # 复制基础元素并修改属性 install_copy1 = etree.Element.copy(base_install) install_copy1.set("hauteur", "10") root.mesure.installationsVisibles.append(install_copy1) install_copy2 = etree.Element.copy(base_install) install_copy2.set("distance", "12") root.mesure.installationsVisibles.append(install_copy2) print(etree.tostring(root, pretty_print=True).decode('utf-8'))
修改后的预期输出
执行上述代码后,installationsVisibles节点下会出现多个独立的
<mesures> <mesure> <refMesure>LEM180895</refMesure> <conditions interieur="true" perimetreSecurite="false" champLointain="true"> <duree dateDebut="2018-07-24" heureDebut="10:00" dateFin="2018-07-24" heureFin="12:30"/> <typeEnvironnement>PUBLIC</typeEnvironnement> <complement/> </conditions> <localisation changementAdresse="false"> <motifChangementAdresse/> <position lon="2.3227499999999996" lat="48.8665556" hauteurSol="0"/> <adresse> <voie/> <lieudit/> <complement>string</complement> <codePostal>00000</codePostal> <commune>Commune</commune> </adresse> </localisation> <installationsVisibles> <installation hauteur="8" distance="9"> <type/> </installation> <installation hauteur="10" distance="9"> <type/> </installation> <installation hauteur="8" distance="12"> <type/> </installation> </installationsVisibles> <resultat respectNiveauReference="false"> <valeurMoyenne>0</valeurMoyenne> <!--You have a CHOICE of the next 3 items at this level--> <!--Optional:--> </resultat> </mesure> </mesures>
内容的提问来源于stack exchange,提问作者Gus tutu
相关产品推荐
相关产品推荐

