I am trying to parse a XML like this:
<?xml version="1.0" encoding="UTF-8"?>
<gml:FeatureCollection
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:p="http://example.org">
<gml:featureMember>
<p:Point>
<gml:pointProperty>
<gml:Point srsName="epsg:4258">
<gml:pos>-3.84307585 43.46031547</gml:pos>
</gml:Point>
<gml:Point srsName="epsg:4258">
<gml:pos>-3.84299411 43.46018513</gml:pos>
</gml:Point>
<gml:Point srsName="epsg:4258">
<gml:pos>-3.84299935 43.45998723</gml:pos>
</gml:Point>
<!--
... many more <gml:Point> nodes ...
-->
<gml:Point srsName="epsg:4258">
<gml:pos>-3.84309913 43.46054546</gml:pos>
</gml:Point>
<gml:Point srsName="epsg:4258">
<gml:pos>-3.84307585 43.46031547</gml:pos>
</gml:Point>
</gml:pointProperty>
</p:Point>
</gml:featureMember>
</gml:FeatureCollection>
I want to get each of gml:pos
rows to save to a DB but for the moment I am happy printing them in webpace (echo
...)
$output = simplexml_load_string($output);
$xml = $output->getNamespaces(true);
//print_r( $xml);
$xml_document = $output->children($xml["p"]);
foreach($xml_document->Point->children($xml["gml"]);
echo $xml_point->Point[0];
echo $xml->FeatureCollection;
}
In $output I have the complete xml, tons of coordinates in gml:point
But I am trying to get to the points using namespaces but I have to be doing something wrong because I can't print anything but Array word (even by using print_r
...)
You should not read the namespaces from the document. The namespace is a unique string defining the XML semantic the tag is part of. Your XML is a good example for that, because it has
Point
elements in two different namespaces.p:Point
is {http://example.org}:Pointgml:Point
is {http://www.opengis.net/gml}:PointThe namespace prefixes like
p
andgml
are aliases to make a document smaller and more readable. They are only valid for the element and its children. They can be redefined at any point. More important they are only valid for the document.So to read XML you define own prefixes for the namespaces and use them with Xpath or you use the namespace aware variants of the DOM methods like
getAttributeNS()
. Xpath is by a long way the more elegant solution. You can use the prefixes from the document or different ones.Output: https://eval.in/159739
This would be easier using XPath, since you have nodes nested deeply in alternating namespaces, but since you are using SimpleXML I'll show you a solution using that framework.
This
won't work because the root node has no children in the
p
namespace. You have to navigate the tree until you are in the right context. With XPath you could fetch them all with adescendant
axis expression, which would be simpler. The code below works with SimpleXML:Now you can loop on the children of
pointProperty
and you will have yourPoint
nodes:From there on, the namespace doesn't change, so you can navigate normally and get the data in the
pos
elements. Here is an example:This will print a table containing your data. You can adapt this to fit your needs:
Here's a working PHP Fiddle you can try out online.