0

I'm trying to load some data in from a GPX file.

The file has been downloaded from Garmin Connect (https://connect.garmin.com) and has a few custom extensions for things like heart rate etc. For some reason simplexml_load_file() is skipping the extensions and failing to register the namespaces for them.

To be clear, there are two things missing. Most importantly the ns3:* elements are all missing from the output.

<?xml version="1.0" encoding="UTF-8"?>
<gpx creator="Garmin Connect" version="1.1"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/11.xsd"
  xmlns:ns3="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
  xmlns="http://www.topografix.com/GPX/1/1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
  >
   <metadata>
    <link href="connect.garmin.com">
      <text>Garmin Connect</text>
    </link>
    <time>2018-07-06T14:53:04.000Z</time>
  </metadata>
  <trk>
    <name>Stripped</name>
    <type>cycling</type>
    <trkseg>
      <trkpt lat="35.4119682700932025909423828125" lon="-2.3132956029832363128662109375">
        <ele>51.21000152587890625</ele>
        <time>2018-07-06T14:53:04.000Z</time>
        <extensions>
          <ns3:TrackPointExtension>
            <ns3:atemp>28.0</ns3:atemp>
            <ns3:hr>113</ns3:hr>
          </ns3:TrackPointExtension>
        </extensions>
     </trkpt>
     </trkseg>
     </trk>
</gpx>

Really simple code:

$foo = simplexml_load_file("test.xml");
print_r($foo->getNamespaces());
print_r($foo);

Produces this:

Array
(
    [] => http://www.topografix.com/GPX/1/1
    [xsi] => http://www.w3.org/2001/XMLSchema-instance
#### Missing namespaces here ####

)
SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [creator] => Garmin Connect
            [version] => 1.1
        )

    [metadata] => SimpleXMLElement Object
        (
            [link] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [href] => connect.garmin.com
                        )

                    [text] => Garmin Connect
                )

            [time] => 2018-07-06T14:53:04.000Z
        )

    [trk] => SimpleXMLElement Object
        (
            [name] => Stripped
            [type] => cycling
            [trkseg] => SimpleXMLElement Object
                (
                    [trkpt] => SimpleXMLElement Object
                        (
                            [@attributes] => Array
                                (
                                    [lat] => 35.4119682700932025909423828125
                                    [lon] => -2.3132956029832363128662109375
                                )

                            [ele] => 56.40000152587890625
                            [time] => 2018-07-06T14:53:04.000Z
                            [extensions] => SimpleXMLElement Object
                                (
##### Missing extensions here #####
                                )

                        )

                )

        )
Philip Couling
  • 13,581
  • 5
  • 53
  • 85
  • Using recursive=true --> print_r($foo->getNamespaces(true)); I see it returning ns3 too... But don't know if it's enough for you – koalaok Jul 08 '18 at 10:18
  • I need the elements. Thanks for finding me the namespace – Philip Couling Jul 08 '18 at 10:41
  • Sorry... so is that the answer you were looking for? – koalaok Jul 08 '18 at 10:42
  • @koalaok No there's two parts `#### missing ####` the second is way more important. you will need to scroll down to see the second. – Philip Couling Jul 08 '18 at 11:07
  • have a look at the answer at : https://stackoverflow.com/questions/34202967/xmlns-xmlnsxsi-xsischemalocation-and-targetnamespace This may clarify you how namespace definition and usage is intended in XML files. – koalaok Jul 08 '18 at 11:11
  • @koalaok I don't see how that helps, the XML document is well-formed AFAIK. The problem appears to be that PHP isn't reading it, or I'm trying to access the elements in the wrong way. – Philip Couling Jul 08 '18 at 11:37
  • http://php.net/manual/en/simplexml.examples-basic.php – koalaok Jul 08 '18 at 11:40
  • @koalaok I can and have read user manual pages. if you don't know the answer just move on. The last two links you've put on are totally irrelevant. – Philip Couling Jul 08 '18 at 11:56
  • @IMSoP Thanks. That looks like what I needed. – Philip Couling Jul 08 '18 at 12:00

1 Answers1

0

As stated in : http://php.net/manual/en/simplexmlelement.getnamespaces.php

recursive If specified, returns all namespaces used in parent and child nodes. Otherwise, returns only namespaces, if any, none in your case, used in root node.

Namespace ns3 is used in child nodes, you then need to specify recursive to true. Otherwise you get only ns in XML root:

     $foo = simplexml_load_file("test.xml");
     print_r($foo->getNamespaces(TRUE));
koalaok
  • 5,075
  • 11
  • 47
  • 91