简体   繁体   中英

Parsing XML in python with etree

I got an XML file:

<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>antigon</name>
    <SSIDConfig>
        <SSID>
            <name>antigon</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>false</protected>
                <keyMaterial>THIS IS WHAT I WANNA GET</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
    <MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3">
        <enableRandomization>false</enableRandomization>
    </MacRandomization>
</WLANProfile>

I know the logic of HTML/XML, but I can't find how to get the thing "THIS IS WHAT I WANNA GET", with Etree and python, both in last version. Could someone help me? Thanks a lot !

Below

import xml.etree.ElementTree as ET
import re

xml = '''<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>antigon</name>
    <SSIDConfig>
        <SSID>
            <name>antigon</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>false</protected>
                <keyMaterial>THIS IS WHAT I WANNA GET</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
    <MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3">
        <enableRandomization>false</enableRandomization>
    </MacRandomization>
</WLANProfile>'''
xml = re.sub(' xmlns="[^"]+"', '', xml, count=1)
root = ET.fromstring(xml)
key_material = root.find('.//keyMaterial')
print(key_material.text)

output

THIS IS WHAT I WANNA GET

See the docs (and this answer ) for details on handling namespaces with ElementTree.

Here's an example:

import xml.etree.ElementTree as ET

ns_map = {"wlan": "http://www.microsoft.com/networking/WLAN/profile/v1"}

tree = ET.parse("input.xml")

print(tree.find(".//wlan:keyMaterial", namespaces=ns_map).text)

prints...

THIS IS WHAT I WANNA GET

If you want to modify that value and save it to a file, try something like this:

import xml.etree.ElementTree as ET

ns_map = {"wlan": "http://www.microsoft.com/networking/WLAN/profile/v1"}

# Need this to make sure a prefix isn't added to your namespace declaration.
ET.register_namespace("", ns_map.get("wlan"))

tree = ET.parse("input.xml")

try:
    tree.find(".//wlan:keyMaterial", namespaces=ns_map).text = "NEW VALUE!"
except AttributeError:
    print("Unable to modify the keyMaterial value.")

tree.write("output.xml", xml_declaration=True, encoding="utf-8")

Output (output.xml)

<?xml version='1.0' encoding='utf-8'?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1" xmlns:ns1="http://www.microsoft.com/networking/WLAN/profile/v3">
    <name>antigon</name>
    <SSIDConfig>
        <SSID>
            <name>antigon</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>false</protected>
                <keyMaterial>NEW VALUE!</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
    <ns1:MacRandomization>
        <ns1:enableRandomization>false</ns1:enableRandomization>
    </ns1:MacRandomization>
</WLANProfile>

Note: ElementTree doesn't do a great job handling more than one default namespace, so that's why the "ns1" prefix is added to the output.

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