Shatners Shatners - 1 year ago 108
Python Question

lxml - Default name spaces

I am trying to parse an xml file using


my_tree = etree.parse(file)
my_root = my_tree.getroot()

for child in my_root:

# {some default namespace}Prop
# {some default namespace}Prop
# {some default namespace}Stuff
# ...

Ideally, I just want to get all the elements I want with something like

my_root.findall('Prop', my_root.nsmap)

but this is returning an empty list. I noticed that the
dictionary had a None item with the default namespace.

nsmap = {None: 'default namespace', ...}

I found a quick workaround by copying the nsmap and adding a 'default' item with the same value as the None item, and then I do

my_root.findall('default:Prop', new_map)

This feels very hackish. Why is None even in the namespace map? Is there some straightforward method in lxml the automatically uses the default namespace?

Edit: The xml I am looking at is along the lines of

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ScenarioProps xmlns="" xmlns:ns2="" id="Test">
<Prop id="Wi-Fi">
<ns2:Position x="0.0" y="0.0" z="0.0"/>
<ns2:Orientation roll="0.0" pitch="0.0" yaw="0.0"/>

Answer Source

Hackish or not, you have to specify a prefix. XPath 1.0, which is what lxml supports, does not have a concept of default namespace (it works differently in XPath 2.0, but that does not apply here).

The other option is to not bother with prefixes at all. Use the fully qualified element name in "Clark notation" instead:


See also

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download