This question already has an answer here:
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 #####
)
)
)
)
</div>
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));