0

XML response is not easily parsing into an Element Tree object.

I have tried parsing as a string and finding and replacing values, it gets very messy, parsing XML must be easier than this?

    import requests
    from lxml import etree

    response = requests.get(url="http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik")

    root = etree.fromstring(response.content)

    for child in root:
        print (child.tag, child.attrib)

    print(etree.tostring(root, pretty_print=True))   

I expect the Element Tree object to print in a prettify format and my Root to have many children. The Tree object does not print in this manner and the Root looks to have no children.

Am I able to collate here best practice information on parsing XML using this method, thank you.

2
  • try "root = etree.fromstring(response.content).getroottree()" Commented May 30, 2019 at 16:20
  • Do you just want to print the XML or extract information from the tree? Commented May 31, 2019 at 10:41

1 Answer 1

1

Try this code:

import xml.etree.ElementTree as ET
import requests
import re

r = requests.get(
    'http://www.yournavigation.org/api/1.0/gosmore.php?forat=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik')
if r.status_code == 200:
    # remove namespace
    xmlstring = re.sub(' xmlns="[^"]+"', '', r.content, count=1)
    root = ET.fromstring(xmlstring)
    ET.dump(root)

output

<kml>
  <Document>
    <name>KML Samples</name>
    <open>1</open>
    <distance>21.452372</distance>
    <traveltime>1228</traveltime>
    <description>To enable simple instructions add: 'instructions=1' as parameter to the URL</description>
    <Folder>
      <name>Paths</name>
      <visibility>0</visibility>
      <description>Examples of paths.</description>
      <Placemark>
        <name>Tessellated</name>
        <visibility>0</visibility>
        <description>If the &lt;tessellate&gt; tag has a value of 1, the line will contour to the underlying terrain</description>
        <LineString>
          <tessellate>1</tessellate>
          <coordinates> 5.963585,52.215950
5.963585,52.215950
5.963563,52.215986
5.963552,52.216012
5.964570,52.216254
5.964680,52.216333
5.964812,52.216371
5.966120,52.216622
5.967970,52.217000
5.968272,52.217056
5.969040,52.216970
5.969243,52.216943
5.969853,52.216862
5.969980,52.216840
5.970410,52.216760
5.970430,52.216757
5.970608,52.216718
5.970875,52.216652
5.971517,52.216534
5.972517,52.216352
5.972689,52.216347
5.972828,52.216322
5.973490,52.216180
5.974320,52.216020
5.974858,52.215917
5.975508,52.215795
5.975618,52.215774
5.975806,52.215736
5.975964,52.215707
5.976454,52.215615
5.976790,52.215550
5.977030,52.215500
5.978012,52.215322
5.978128,52.215301
5.978297,52.215269
5.978550,52.215223
5.979900,52.214980
5.979972,52.214967
5.980610,52.214850
5.981604,52.214682
5.982088,52.214593
5.982319,52.214555
5.983603,52.214328
5.983800,52.214290
5.984046,52.214244
5.984611,52.214147
5.984766,52.214123
5.984979,52.214089
5.985825,52.213893
5.985988,52.213862
5.986167,52.213827
5.986373,52.213785
5.987057,52.213667
5.987258,52.213647
5.988991,52.213331
5.991815,52.212817
5.993959,52.212422
5.996034,52.212043
5.996967,52.211876
5.997648,52.211743
5.998927,52.211492
5.999520,52.211376
5.999731,52.211334
5.999916,52.211301
6.000084,52.211273
6.000583,52.211188
6.003432,52.210674
6.004653,52.210453
6.004780,52.210428
6.004768,52.210359
6.004796,52.210315
6.004844,52.210283
6.004888,52.210267
6.004979,52.210256
6.005070,52.210271
6.005135,52.210305
6.005173,52.210356
6.005279,52.210337
6.008708,52.209720
6.011155,52.209269
6.012734,52.208984
6.012875,52.208959
6.012863,52.208920
6.012867,52.208894
6.012891,52.208857
6.012923,52.208833
6.012978,52.208812
6.013050,52.208803
6.013133,52.208814
6.013185,52.208838
6.013344,52.208817
6.013912,52.208709
6.014164,52.208648
6.014589,52.208512
6.014934,52.208433
6.015404,52.208346
6.018004,52.207885
6.019191,52.207672
6.019602,52.207601
6.020681,52.207393
...
          </coordinates>
        </LineString>
      </Placemark>
    </Folder>
  </Document>
</kml>
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the assistance, I receive the error cannot use a string pattern on a bytes-like object
Adding this on the 9th line fixed the issue xmlstring = re.sub(' xmlns="[^"]+"', '', r.content.decode('utf-8'), count=1)
What is the python version that you are using? (I have tested the code under python 3.6)
I am using 3.7, the request response was coming through as a byte object before too. I will vote you as the answer as it got me 99% of the way. Also to note as the response is kml to iterate to co-ordinates I used for element in root.getiterator("coordinates"): print (element.text)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.