1

I've got a KML file - I'm using the wikipedia 'default' as a sample:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Placemark>
  <name>New York City</name>
  <description>New York City</description>
  <Point>
    <coordinates>-74.006393,40.714172,0</coordinates>
  </Point>
</Placemark>
</Document>
</kml>

And I'm trying to extract the coordinates.

Now, I've got a snippet working that embeds the namespace to search:

#!/usr/python/python3.4/bin/python3

from lxml import etree as ET

tree = ET.parse('sample.kml')
root = tree.getroot

print (root.find('.//{http://www.opengis.net/kml/2.2}coordinates').text)

This works fine.

However having found this:

Parsing XML with namespace in Python via 'ElementTree'

I'm trying to do it via reading the namespace from the document, using 'root.nsmap'.

print (root.nsmap)

Gives me:

{None: '{http://www.opengis.net/kml/2.2}'}

So I think I should be able to do this:

print ( root.find('.//coordinates',root.nsmap).text )

Or something very similar, using the None namespace. (e.g. has no prefix). But this doesn't work - I get an error when doing it:

AttributeError: 'NoneType' object has no attribute  'text'

I assume that means that my 'find' didn't find anything in this instance.

What am I missing here?

Community
  • 1
  • 1
Sobrique
  • 52,974
  • 7
  • 60
  • 101

1 Answers1

1

This code,

root.find('.//coordinates', root.nsmap)

does not return anything because no prefix is used. See http://lxml.de/xpathxslt.html#namespaces-and-prefixes.

Below are two options that work.

  1. Define another nsmap with a real prefix as key:

    nsmap2 = {"k": root.nsmap[None]}
    print (root.find('.//k:coordinates', nsmap2).text)
    
  2. Don't bother with prefixes. Put the namespace URI inside curly braces ("Clark notation") to form a universal element name:

    ns = root.nsmap[None]
    print (root.find('.//{{{0}}}coordinates'.format(ns)).text)
    
mzjn
  • 48,958
  • 13
  • 128
  • 248