Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

findall doesn't return anything with document with namespace #127

Closed
s-celles opened this issue Nov 10, 2019 · 4 comments
Closed

findall doesn't return anything with document with namespace #127

s-celles opened this issue Nov 10, 2019 · 4 comments

Comments

@s-celles
Copy link

Hello,

I'm trying to parse a KML file sample.kml with gx:Track tag

My code is:

using Dates
using EzXML

function read_kml(fname)
    xdoc = readxml(fname)
    kmls = root(xdoc)

    lst_when = findall("//Placemark/Track/when/text()", kmls)
    lst_when = nodecontent.(lst_when)
    lst_when = parse.(DateTime, lst_when, dateformat"yyyy-mm-dd\THH:MM:SSZ")
    println(lst_when)

    lst_coords = findall("//Placemark/Track/coord/text()", kmls)
    lst_coords = nodecontent.(lst_coords)
    lst_coords = split.(lst_coords)
    println(lst_coords)

    g = ((when, parse.(Float64, coord)...) for (when, coord) in zip(lst_when, lst_coords))

    return ((dt=when, longitude=longitude, latitude=latitude, altitude=altitude) for (when, longitude, latitude, altitude) in g)
end

fname = "sample.kml"
# fname = "sample_no_ns.kml"

itr = read_kml(fname)
# println(itr)

for x in itr
    println(x)
end

but I don't get anything.

If I remove namespace in kml file like in sample_no_ns.kml I get appropriate result ie I wonder if findall function handle correctly namespaces (or if that's a misunderstanding from my side how EzXML is working).

I did a similar program in Python cleder/fastkml#37 (comment) and it works fine

Any idea what is wrong?

julia> fname = "sample.kml"
"sample.kml"

julia> using Dates

julia> using EzXML

julia> xdoc = readxml(fname)
EzXML.Document(EzXML.Node(<DOCUMENT_NODE@0x00007f8286bcde20>))

julia> kmls = root(xdoc)
EzXML.Node(<ELEMENT_NODE[kml]@0x00007f8285713ab0>)

julia> lst_when = findall("//Placemark/Track/when/text()", kmls)
0-element Array{EzXML.Node,1}

findall shouldn't return an empty Array

Kind regards

@s-celles
Copy link
Author

I also tried passing namespaces to findall

julia> lst_when = findall("//Placemark/Track/when/text()", kmls, namespaces(kmls))
0-element Array{EzXML.Node,1}

but it didn't helped

@bicycle1885
Copy link
Member

You'll need to give some explicit name to the default anonymous namespace. Also, please don't forget to mention namespaces in the Xquery:

julia> doc = readxml("sample.kml")
EzXML.Document(EzXML.Node(<DOCUMENT_NODE@0x00007fb3089b2940>))

julia> ns = namespaces(doc.root)
2-element Array{Pair{String,String},1}:
   "" => "http://www.opengis.net/kml/2.2"
 "gx" => "http://www.google.com/kml/ext/2.2"

julia> ns[1] = "x" => ns[1][2]
"x" => "http://www.opengis.net/kml/2.2"

julia> ns
2-element Array{Pair{String,String},1}:
  "x" => "http://www.opengis.net/kml/2.2"
 "gx" => "http://www.google.com/kml/ext/2.2"

julia> findall("//x:Placemark/gx:Track/x:when/text()", doc.root, ns)
45-element Array{EzXML.Node,1}:
 EzXML.Node(<TEXT_NODE@0x00007fb308c3ea90>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064c6b20>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064f6b00>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064c9670>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c42e70>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c41630>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064d4c40>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c4f270>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c3b800>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064ebd70>)
 EzXML.Node(<TEXT_NODE@0x00007fb30649fc80>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064acf70>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064a6750>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064ef580>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c3e230>)
 EzXML.Node(<TEXT_NODE@0x00007fb30649ecb0>)
 ⋮
 EzXML.Node(<TEXT_NODE@0x00007fb308c28b50>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c29440>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c29d30>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c22340>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c17100>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c17c60>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c18520>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064eea30>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064c99f0>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c50880>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c3a440>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c4b960>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c13730>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064e8950>)
 EzXML.Node(<TEXT_NODE@0x00007fb3064a0070>)
 EzXML.Node(<TEXT_NODE@0x00007fb308c2c030>)

@s-celles
Copy link
Author

Thanks @bicycle1885 for your help.

It's quit odd to have to pass namespaces(kmls) to findall especially as we pass kmls so namespace can directly find by findall function.

An other odd API idea is that I absolutely need to overwrite default namespace name "" to "x".

I'm wondering if an other approach which might fallback to default namespace shouldn't be used.

Anyway thanks again for your help... it helped me much!

@bicycle1885
Copy link
Member

The gory details of XPath are so clumsy that trying to do some fancy stuff may result in more confusing APIs. If you have any suggestions or improvement ideas, feel free to open a proposal issue here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants