I am trying to find a XML child element, and this child element has its default namespace, which is different from parent element's name space. I want to find the child element and change its text value using LXML.
The xml child element with the default namespace is:
<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac>
The idea is:
1.input parameters:
- the element xpath: ".//interfaces/interface/mac":
- the order of all the same element: the first
- the element text's new value: 10
2.find the element:
<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac>
My code:
XML file test.xml:
<?xml version='1.0' encoding='utf-8'?>
<a:config xmlns:a="urn:base:1.0">
<interfaces xmlns="urn:a-interfaces">
<interface>
<name>eth0</name>
<enabled>true</enabled>
<ipv4 xmlns="urn:b-ip">
<enabled>true</enabled>
</ipv4>
<tagging xmlns="urn:b:interfaces:1.0">true</tagging>
<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac>
</interface>
<interface>
<name>eth0-A</name>
<enabled>true</enabled>
<ipv4 xmlns="urn:b-ip">
<enabled>true</enabled>
</ipv4>
<base-interface xmlns="urn:b:interfaces:1.0">eth0</base-interface>
<id xmlns="urn:b:interfaces:1.0">1</id>
<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac>
</interface>
</interfaces>
</a:config>
Python code:
def set_element_value(file_name, element, new_value, element_order):
filename = file_name
tree = etree.parse(filename)
root = tree.getroot()
xml_string = etree.tostring(tree).decode('utf-8')
name_space_dict = {}
for node in root:
name_space_dict = dict(node.nsmap)
count_order = 0
for ele in root.findall(element, namespaces=name_space_dict):
if count_order == element_order:
ele.text = str(new_value)
count_order += 1
def main():
filename ="../test.xml"
element_xpath = ".//interfaces/interface/mac"
new_value = "10"
element_order = 0
set_element_value(filename, element_xpath, new_value, element_order)
if __name__ == '__main__':
main()
My python code cannot find:
<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac>
But if I remove the name space of "mac" to:
<mac>00:00:10:00:00:11</mac>
then the python code works well.
How can I parse the child element which has default name space?
I spent several days to find the root cause for this issue, but it seems that there is no same topic discussed.
Could you please help me about this? Thanks in advance!