Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
916 views
in Technique[技术] by (71.8m points)

xpath - Lxml and python : iterate only over existing elements

I have a KML file which contains 2 placemarks : Test1 and Test2.

<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
  <Placemark>
    <name>Test1</name>
    <styleUrl>style1</styleUrl>
    <Point><coordinates>1,2</coordinates></Point>
    <ExtendedData xmlns:mwm="https://example">
      <mwm:visibility>1</mwm:visibility>
    </ExtendedData>
  </Placemark>
  <Placemark>
    <name>Test2</name>
    <styleUrl>style2</styleUrl>
    <Point><coordinates>3,4</coordinates></Point>
    <ExtendedData xmlns:mwm="https://example">
      <mwm:scale>19</mwm:scale>
      <mwm:visibility>1</mwm:visibility>
    </ExtendedData>
  </Placemark>
</Document>
</kml>

Test2 has an element < mwm:scale > while Test1 does not.

My goal is to loop through all placemarks, and record in a list all placemarks' names and in another list all placemarks' scale.

I've been digging around lxml and Xpath option, but I can't find a way to have an "empty" output when the element (in this case "scale") doesn't exist in the Placemark (parent element).

This code :

import lxml.etree as et
tree  = et.parse(file.kml)
for names in tree.xpath("/kml:kml/kml:Document/kml:Placemark/kml:name", namespaces={'kml': 'http://earth.google.com/kml/2.2','mwm': 'https://example'}):
  name_list.append(names.text)

for scales in tree.xpath("/kml:kml/kml:Document/kml:Placemark/kml:ExtendedData/mwm:scale", namespaces={'kml': 'http://earth.google.com/kml/2.2','mwm': 'https://example'}):
  scale_list.append(scales.text)

will give me those list

[Test1, Test2]

[19]

while I'm looking for a solution to get something like (if scale doesn't exist, output '0') :

[Test1, Test2]

[0, 19]

Any solution or idea ? I've been trying to iterate through the parsed XML but the 2 different namespaces (kml and mwm) make it impossible with the solutions I've find on the forum....

Thanks a lot for any help !

question from:https://stackoverflow.com/questions/65906998/lxml-and-python-iterate-only-over-existing-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try something along these lines:

name_list = []
scale_list = []
ns = {'kml': 'http://earth.google.com/kml/2.2','mwm': 'https://example'}
for name in tree.xpath("/kml:kml/kml:Document/kml:Placemark/kml:name", namespaces=ns):
    name_list.append(name.text)    
    scale =  name.xpath("following-sibling::kml:ExtendedData//mwm:scale", namespaces=ns)
    if len(scale)==0:
        scale_list.append("0")
    else:
        scale_list.append(scale[0].text)

Output:

(['Test1', 'Test2'], ['0', '19'])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...