简体   繁体   中英

Replacing a xml element with lxml

I have this complex xml file and we need to dynamically update some elements in it. I have successfully been able to update value strings (attributes) using lxml, but I'm completely unsure how to go about replacing an entire element. Here's some pseudo-code to show what I'm trying to do. import os from lxml import etree

directory_name = "C:\\apps"
file_name = "web.config"

xpath_identifier = '/configuration/applicationSettings/Things/setting[@name="CorsTrustedOrigins"]'

#contents of the xml file for reference:
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="Things" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <appSettings/>   
  <applicationSettings>
    <Things>
      <setting name="CorsTrustedOrigins" serializeAs="Xml">
        <value>
          <ArrayOfString>
           <string>http://localhost:51363</string>
           <string>http://localhost:3333</string>
          </ArrayOfString>
        </value>
      </setting>
    </Things>
  </applicationSettings>
</configuration>

file_full_path = os.path.join(directory_name, file_name)
tree = etree.parse(file_full_path)
root = tree.getroot()

etree.tostring(root)


xpath_identifier = str(xpath_identifier)

value = root.xpath(xpath_identifier)

#This successfully prints the element I'm after, so I'm sure my xpath is good:
etree.tostring(value[0])

#This is the new xml element I want to replace the current xpath'ed element with:
newxml = '''
<setting name="CorsTrustedOrigins" serializeAs="Xml">
        <value>
          <ArrayOfString>
            <string>http://maddafakka</string>
          </ArrayOfString>
        </value>
      </setting>
'''

newtree = etree.fromstring(newxml)

#I've tried this:
value[0].getparent().replace(value[0], newtree)

#and this
value[0] = newtree

#The value of value[0] gets updated, but the "root document" does not.

What I'm trying to do is to update the "ArrayofStrings" element to reflect the values in the "newxml" var.

I'm kindof struggling to navigate the lxml infos on the web, but I can't seem to find an example similar to what I'm trying to do.

Any pointers appreciated!

You should just remove the indexed access on the node:

value[0].getparent().replace(value[0], newtree)

.... to: value.getparent().replace(value, newtree)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM