1

My goal is to find the XML child element which has a default name.

XML:

<?xml version='1.0' encoding='UTF-8'?>
<all:config xmlns:all="urn:base:1.0">
    <interfaces xmlns="urn:ietf-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>
  </interfaces>
</all:config>

I want to find the following element:

<mac xmlns="urn:b:interfaces:1.0">00:00:10:00:00:11</mac> 

and change mac's text.

I have the following questions:

  1. What is the xpath of mac?
  2. How can I find "mac" using xpath since it has the default namespace?

My code does not work:

def set_element_value(file_name, element, new_value, order):
    filename = file_name
    tree = etree.parse(filename)
    root = tree.getroot()
    xml_string = etree.tostring(tree).decode('utf-8')
    my_own_namespace_mapping = {'prefix': 'urn:b:interfaces:1.0'}
    myele = root.xpath('.//prefix:mac', namespaces=my_own_namespace_mapping)
    myele[0].text = "aaa"
    for ele in root.xpath('.//prefix:mac', namespaces=my_own_namespace_mapping):
        if count_order == order:
            ele.text = str(new_value)
        count_order += 1
def main():
    filename ="./template/b.xml"
    element = ".//interfaces/interface/mac"
    new_value = "10"
    order = 0
    set_element_value(filename, element, new_value, order)
if __name__ == '__main__':
    main()

I tried to dig out in the stackoverflow, but no similar answer.

Could you please give me some tips? Thank you!

2 Answers 2

1

Thanks to Jack's methods, I fixed this issue:

The new code:

def set_element_value(file_name, element, new_value, order):
    filename = file_name
    tree = etree.parse(filename)
    tag_list = tree.xpath('.//*[local-name()="mac"]')
    print("tag:", tag_list, " and tag value:", tag_list[0].text)
    tag_list[0].text = "10"
    xml_string = etree.tostring(tree).decode('utf-8')
    print(xml_string)

def main():
    filename ="./template/b.xml"
    element = "mac"
    new_value = "10"
    order = 1
    set_element_value(filename, element, new_value, order)

if __name__ == '__main__':
    main()

output:

tag: [<Element {urn:ietf-interfaces}mac at 0x298fc4b69c0>]  and tag value: 10
<all:config xmlns:all="urn:base:1.0">
    <interfaces xmlns="urn:ietf-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 xmln="urn:b:interfaces:1.0">10</mac>
        </interface>
  </interfaces>
</all:config>
Sign up to request clarification or add additional context in comments.

Comments

0

Your code seems to be a little too complicated than necessary. Try the following to get to the mac address:

ns = {"x":"urn:b:interfaces:1.0"}
root.xpath('//x:mac/text()',namespaces=ns)[0]

or if you don't want to deal with namespaces:

root.xpath('//*[local-name()="mac"]/text()')[0]

Output in either case is

00:00:10:00:00:11

1 Comment

Yes! Your methods work well! Really great thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.