stack user stack user - 5 months ago 18
Python Question

parsing xml using python / elementree

The xml I need to search specifies but does not use a namespace:

<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
<DATA>
<PROTECTINFO>
<KEYLEN>16</KEYLEN>
<ALGID>AESCTR</ALGID>
</PROTECTINFO>

<LA_URL>http://192.168.8.33/license/rightsmanager.asmx</LA_URL>
<LUI_URL>http://192.168.8.33/license/rightsmanager.asmx</LUI_URL>

<DS_ID></DS_ID>
<KID></KID>
<CHECKSUM></CHECKSUM>

</DATA>
</WRMHEADER>


I'd like to read the values for various fields, e.g. data/protectinfo/keylen etc.

root = ET.fromstring(sMyXml)
keylen = root.findall('./DATA/PROTECTINFO/KEYLEN')

print root
print keylen


This code prints the following:

<Element {http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}WRMHEADER at 0x7f2a7c35be60>
[]


root.find and root.findall return None or [] for this query. I've been unable to specify a default namespace, is there a solution to querying these values?
thanks

Answer

Create a namespace dict:

x = """<WRMHEADER xmlns="http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader" version="4.0.0.0">
    <DATA>
        <PROTECTINFO>
            <KEYLEN>16</KEYLEN>
            <ALGID>AESCTR</ALGID>
        </PROTECTINFO>

        <LA_URL>http://192.168.8.33/license/rightsmanager.asmx</LA_URL>
        <LUI_URL>http://192.168.8.33/license/rightsmanager.asmx</LUI_URL>

        <DS_ID></DS_ID>
        <KID></KID>
        <CHECKSUM></CHECKSUM>

    </DATA>
</WRMHEADER>"""
from xml.etree import ElementTree as ET

root = ET.fromstring(x)
ns = {"wrm":"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader"}
keylen = root.findall('wrm:DATA', ns)

print root
print keylen

Now you should get something like:

<Element '{http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}WRMHEADER' at 0x7fd0a30d45d0>
[<Element '{http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader}DATA' at 0x7fd0a30d4610>]

To get /DATA/PROTECTINFO/KEYLEN:

In [17]: root = ET.fromstring(x)

In [18]: ns = {"wrm":"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader"} 
In [19]: root.find('wrm:DATA/wrm:PROTECTINFO/wrm:KEYLEN', ns).text
Out[19]: '16'