使用 etree 解析 python 中的 XML

Parsing XML in python with etree

我得到了一个 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>

我知道 HTML/XML 的逻辑,但我找不到如何通过 Etree 和 python 获得东西 "THIS IS WHAT I WANNA GET",这两个版本都在上一个版本中。有人可以帮我吗?非常感谢!

低于

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)

输出

THIS IS WHAT I WANNA GET

See the docs (and ) 了解有关使用 ElementTree 处理名称空间的详细信息。

这是一个例子:

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)

打印...

THIS IS WHAT I WANNA GET

如果您想修改该值并将其保存到文件中,请尝试如下操作:

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.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>

注意:ElementTree 在处理多个默认命名空间方面表现不佳,因此这就是为什么要将 "ns1" 前缀添加到输出中的原因。