Parse XML namespaces into array not dict
Bug report.
One of my devices sends XML with multiple xmlns attributes. In a dict these get lost:
import io
import xml.etree.ElementTree as ET
xml = '''<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<X_Rhapsody-Extension xmlns="http://www.real.com/rhapsody/xmlns/upnp-1-0" />
<qq:X_QPlay_SoftwareCapability xmlns:qq="http://www.tencent.com" />
</root>'''
print(dict(elem for (event, elem) in ET.iterparse(io.StringIO(xml), events=['start-ns'])).values())
print([el[1][1] for el in ET.iterparse(io.StringIO(xml), events=['start-ns'])])
Suggestion
diff --git pa_dlna/upnp/xml.py pa_dlna/upnp/xml.py
index c6fe582..9767d1e 100644
--- pa_dlna/upnp/xml.py
+++ pa_dlna/upnp/xml.py
@@ -27,9 +27,9 @@ class UPnPXMLError(UPnPError): pass
# XML helper functions.
@functools_cache
-def namespace_as_dict(xml):
- return dict(elem for (event, elem) in ET.iterparse(
- io.StringIO(xml), events=['start-ns']))
+def namespaces(xml):
+ return [ns for (_event, (_qualifier, ns)) in ET.iterparse(
+ io.StringIO(xml), events=['start-ns'])]
def upnp_org_etree(xml):
"""Return the element tree and UPnP namespace from an xml string."""
@@ -209,8 +209,8 @@ class UPnPNamespace:
def __init__(self, xml, prefix):
"""The first namespace in 'xml' starting with 'prefix'."""
- ns = namespace_as_dict(xml)
- for uri in ns.values():
+ ns = namespaces(xml)
+ for uri in ns:
if uri.startswith(prefix):
self.uri = uri
return
I don't know what @functools_cache does, but maybe it's useful to inline the code to not create the temporary array and iterate two times.
Your environment.
- pa-dlna version: 0.14