Is there a way to parse google maps *.kml file with simple_xml_load_file("*.kml") ?
I need to save in my database name and coordinates of each polygons registered in my KML file.
On my PHP script, simple_xml_load_file("*.kml") return false, so I can't read it.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<Schema>
...
</Schema>
<Style id="FEATURES">
...
</Style>
<Folder>
<Placemark>
<name>
name
</name>
<Polygon>
<LinearRing>
<coordinates>
coordinates
</coordinates>
</LinearRing>
</Polygon>
</Placemark>
<Placemark>
...
</Placemark>
</Folder>
</Document>
</kml>
I need "name" and "coordinates" values for each "Placemark".
The xml structure is exactly that xml you sent:
For example:
<Document>
<Placemark>
<name>356HH</name>
<description>
</description>
<Polygon><outerBoundaryIs><LinearRing><coordinates>some cordinates here</coordinates></LinearRing></innerBoundaryIs></Polygon>
<Style><LineStyle><color>ff0000ff</color></LineStyle> <PolyStyle><fill>0</fill></PolyStyle></Style>
</Placemark>
<Placemark>
</document>
And it's my php code:
<?php
$completeurl = "2.xml";
$xml = simplexml_load_file($completeurl);
$placemarks = $xml->Document->Placemark;
$con=mysqli_connect("localhost","root","","j3");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$query = '';
$run='';
for ($i = 0; $i < sizeof($placemarks); $i++) {
$coordinates = $placemarks[$i]->name;
$cor_d = explode(' ', $placemarks[$i]->Polygon->outerBoundaryIs->LinearRing->coordinates);
$qtmp=array();
foreach($cor_d as $value){
$tmp = explode(',',$value);
$ttmp=$tmp[1];
$tmp[1]=$tmp[0];
$tmp[0]=$ttmp;
$qtmp[]= '(' . $tmp[0] . ',' .$tmp[1].')';
}
$cor_d = json_encode($qtmp);
$query .='\''.$coordinates.'\', \''.$cor_d.'\'';
$run .="INSERT INTO jos_rpl_addon_zipinfo (name, boundary) VALUES (".$query." );";
//echo $run;
//break;
}
mysqli_query($con,$run);
//echo $run;
mysqli_close($con);
?>
The first line:
<?xml version="1.0" encoding="UTF-8"?>
Tells PHP that this is a document encoded in UTF-8, but your error says it is not encoded as UTF-8. Is this a doc you created with a text editor? If so, you can usually use your editor to save it out in UTF-8. Or you can probably use PHP to detect the encoding and change that first line.
If the XML strucutre is as what you have posted, you can try :-
$xml = simplexml_load_file(...);
$childs = $xml->Document->Folder->children();
foreach ($childs as $child)
{
// child object is same as -> Placemark
}
Example :-
SimpleXMLElement Object
(
[name] =>
name
[Polygon] => SimpleXMLElement Object
(
[LinearRing] => SimpleXMLElement Object
(
[coordinates] =>
coordinates
)
)
)
Related
I'm trying to create XML from an array in the following format
<root>
<kyero>
<feed_version>3</feed_version>
</kyero>
<property>
<id>12367</id>
<date>2013-09-27 12:00:10</date>
<ref>V3TEST</ref>
<price>250000</price>
<currency>EUR</currency>
<price_freq>sale</price_freq>
<leasehold>0</leasehold>
<type>villa</type>
<town>almunecar</town>
<province>granada</province>
<country>spain</country>
<location>
<latitude>36.728807</latitude>
<longitude>-3.693466</longitude>
</location>
<features>
<feature>good rental potential</feature>
<feature>near beach</feature>
<feature>water possible</feature>
</features>
<notes>Private property notes</notes>
<images>
<image id="1">
<url>http://images.kyero.com/12811577_large.jpg</url>
</image>
<image id="2">
<url>http://images.kyero.com/12811578_large.jpg</url>
</image>
<image id="3">
<url>http://images.kyero.com/12811579_large.jpg</url>
</image>
<image id="4">
<url>http://images.kyero.com/12811581_large.jpg</url>
</image>
<image id="50">
<url>http://images.kyero.com/12811582_large.jpg</url>
</image>
</images>
</property>
</root>
The important take away is the nested arrays such as <features> and <images>.
An example of my array that I've built so far is:
Array
(
[kyero] => Array
(
[feed_version] => 3
)
[0] => Array
(
[id] => 2024
[ref] => jtl-2024-4202
[date] => 2019-11-19 15:34:39
[title] => A wonderful property
[price] => 14828
[price_freq] => month
[country] => United Kingdom
[location] => Array
(
[latitude] => 55.311512
[longitude] => -2.9378154999999
)
[features] => Array
(
[0] => Prominent Building
[1] => Great Location
[2] => Grade A Office Space
[3] => Air Conditioning
[4] => Generous Car Parking
)
[images] => Array
(
[0] => Array
(
[url] => https://example.com/image1.jpg
)
[1] => Array
(
[url] => https://example.com/image2.jpg
)
)
)
)
And the code to convert the array to XML
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><root></root>');
//$data = array as shown above
array_to_xml($data, $xml_data);
The specific issue lies within this method
function array_to_xml($data, &$xml_data, $isImg = FALSE, $isFeature = FALSE) {
$i = 1;
foreach ($data as $key => $value) {
if (is_numeric($key)) {
$key = 'property'; //dealing with <0/>..<n/> issues
if($isImg){
$key = 'image';
}
if($isFeature){
$key = 'feature';
}
}
if (is_array($value)) {
if($key == 'images'){
$isImg = true;
} elseif($key == 'features'){
$isFeature = true;
}
$subnode = $xml_data->addChild($key);
if($key == 'image'){
$subnode->addAttribute('id', $i);
}
array_to_xml($value, $subnode, $isImg, $isFeature);
} else {
$xml_data->addChild("$key", htmlspecialchars("$value"));
}
$i++;
}
}
The output of the XML comes out as desired except for a few parts, specifically the nested parts like features and images.Note how each <url> is wrapped in a <feature> node. This should be a <image> node instead like shown in the originally XML shown at the start of this question, in addition to the id attributes on the image nodes as well.
(the <location> doesn't suffer from the same problem)
<features>
<feature>Prominent Building</feature>
<feature>Great Location</feature>
<feature>Grade A Office Space</feature>
<feature>Air Conditioning</feature>
<feature>Generous Car Parking</feature>
</features>
<images>
<feature>
<url>
https://example.com/image1.jpg
</url>
</feature>
<feature>
<url>
https://example.com/image2.jpg
</url>
</feature>
</images>
If I comment out
if($isFeature){
$key = 'feature';
}
and
elseif($key == 'features'){
$isFeature = true;
}
The images then are formatted correctly
<images>
<image id="1">
<url>
https://example.com/image1.jpg
</url>
</image>
<image id="2">
<url>
https://example.com/image2.jpg
</url>
</image>
</images>
but the features are incorrect, instead they become
<features>
<property>Prominent Building</property>
<property>Great Location</property>
<property>Grade A Office Space</property>
<property>Air Conditioning</property>
<property>Generous Car Parking</property>
</features>
The <property> nodes should be <feature> nodes instead.
Could you help me with the array_to_xml() method to handle these and other nested arrays correctly?
Original conversion code: https://stackoverflow.com/a/5965940/10884442
I agree with ThW about creating the data directly, but I am also a fan of doing things simply and SimpleXML is a good fit with what you are trying to do.
As I don't know how you obtained the data you have so far I will code this using that array, but instead of trying to do a generic flexible version, this shows how easy it is to create the entire structure using SimpleXML.
All it does is use the SimpleXML ability to reference an element by using object notation, the code is quite repetitive, but all it is doing is setting elements form the data in your array...
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><root></root>');
$xml_data->kyero->feed_version = $data['kyero']['feed_version'];
$newProperty = $xml_data->addChild("property");
$newProperty->id = $data[0]['id'];
$newProperty->ref = $data[0]['ref'];
$newProperty->date = $data[0]['date'];
$newProperty->title = $data[0]['title'];
$newProperty->price = $data[0]['price'];
$newProperty->price_freq = $data[0]['price_freq'];
$newProperty->country = $data[0]['country'];
$newProperty->location->latitude = $data[0]['location']['latitude'];
$newProperty->location->longitude = $data[0]['location']['longitude'];
foreach ( $data[0]['features'] as $key => $feature ) {
$newProperty->features->feature[$key] = $feature;
}
$images = $newProperty->addChild("images");
foreach ( $data[0]['images'] as $key => $image ) {
$newImage = $images->addChild("image");
$newImage['id']= $key+1;
$newImage->url = $image['url'];
}
using your sample data, this gives...
<?xml version="1.0"?>
<root>
<kyero>
<feed_version>3</feed_version>
</kyero>
<property>
<id>2024</id>
<ref>jtl-2024-4202</ref>
<date>2019-11-19 15:34:39</date>
<title>A wonderful property</title>
<price>14828</price>
<price_freq>month</price_freq>
<country>United Kingdom</country>
<location>
<latitude>55.311512</latitude>
<longitude>-2.9378154999999</longitude>
</location>
<features>
<feature>Prominent Building</feature>
<feature>Great Location</feature>
<feature>Grade A Office Space</feature>
<feature>Air Conditioning</feature>
<feature>Generous Car Parking</feature>
</features>
<images>
<image id="1">
<url>https://example.com/image1.jpg</url>
</image>
<image id="2">
<url>https://example.com/image2.jpg</url>
</image>
</images>
</property>
</root>
Don't CONVERT, but CREATE. In other words do not try to build and array and implement a generic mapper. It is a lot more difficult. SimpleXML does not allow much control. In DOM here are 3 steps:
Create the node using DOMDocument::create...() methods
Append/Insert the node to its parent node using DOMNode::appendChild()/DOMNode::insertBefore()
Add attributes and child nodes to the node
Here is a small example:
$document = new DOMDocument('1.0', 'UTF-8');
$root = $document->appendChild($document->createElement('root'));
$kyero = $root->appendChild($document->createElement('kyero'));
$kyero->appendChild(
$document->createElement('feed_version')
)->textContent = '3';
$document->formatOutput = TRUE;
echo $document->saveXML();
Output:
<root>
<kyero>
<feed_version>3</feed_version>
</kyero>
</root>
DOMNode::appendChild() returns the appended node, so you can nest the create call.
Changing DOMNode::$textContent replaces all current child nodes with a single text node. Unlike the secondary argument for SimpleXMLElement::addChild()/DOMDocument::createElement() it will properly escape special characters.
I typically implement a method XMLAppendable::appendTo() for XML serializable objects. It allows you to keep the XML create snippets in a maintainable size and add some verification.
interface XMLAppendable {
public function appendTo(DOMElement $parentNode): void;
}
class ImageList implements XMLAppendable {
private $_images = [];
public function __construct(array $images) {
$this->_images = $images;
}
public function appendTo(DOMElement $parentNode): void {
$document = $parentNode->ownerDocument;
$images = $parentNode->appendChild(
$document->createElement('images')
);
foreach ($this->_images as $id => $url) {
$image = $images->appendChild($document->createElement('images'));
$image->setAttribute('id', $id);
$image
->appendChild($document->createElement('url'))
->textContent = $url;
}
}
}
$document = new DOMDocument('1.0', 'UTF-8');
$root = $document->appendChild(
$document->createElement('root')
);
$property = $root->appendChild(
$document->createElement('property')
);
$images = new ImageList(
[
'2' => 'http://images.kyero.com/12811578_large.jpg',
'50' => 'http://images.kyero.com/12811582_large.jpg'
]
);
$images->appendTo($property);
$document->formatOutput = TRUE;
echo $document->saveXML();
I have a log file whose content is like the one below
2016-04-07 19:37:48 <order merchant="asc" affiliate="" id="UM9E-C01101518" date="1443723720" event_id="1" ref="GDVJT" alias="asc">
<event type="sale" date="2015-10-01 18:22:00" status_code="SA">
<sale amount="61.45" amount_usd="43.94" method="VISA" currency="CAD" processor="visa"/>
<tax amount="7.37" amount_usd="5.28" currency="CAD"/>
<payout amount="39.89" currency="USD"/>
</event>
<customer>
<name>Frank</name>
<email>frank#gmail.com</email>
<address/>
<region>BC</region>
<country>IN</country>
<zip_postal>V8V1J9</zip_postal>
<phone_number>1231231234</phone_number>
<language>EN</language>
<ip>209.13.233.227</ip>
<currency>CAD</currency>
</customer>
I am trying to extract the value of name and email from this log file.
I am using the below code:
$handle = fopen('vendorOrder.log','r') or die ('File opening failed');
while (!feof($handle)) {
$dd = fgets($handle);
$str = htmlentities($dd, ENT_XHTML);
if(preg_match("/<name>(.*)<\/name>/",$str)){
$txt = getTextBetweenTags($str, "name");
echo $txt;
}
}
fclose($handle);
function getTextBetweenTags($string, $tagname) {
$pattern = "/<$tagname>(.*)<\/$tagname>/";
preg_match($pattern, $string, $matches);
return $matches[0];
}
But it is never matching the name tag and I am not able to get the value between the tags.
I need the output as Frank.
Can someone let me know whats wrong in the code
Use simplexml_load_file() php function.
Example:
$xml=simplexml_load_file("vendorOrder.log") or die("Error: Cannot create object");
And get this value with $xml->customer->name
Maybe your XML are crashed. Try this format.
<order merchant="asc" affiliate="" id="UM9E-C01101518" date="1443723720" event_id="1" ref="GDVJT" alias="asc">
<event type="sale" date="2015-10-01 18:22:00" status_code="SA">
<sale amount="61.45" amount_usd="43.94" method="VISA" currency="CAD" processor="visa"/>
<tax amount="7.37" amount_usd="5.28" currency="CAD"/>
<payout amount="39.89" currency="USD"/>
</event>
<customer>
<datetime>2016-04-07 19:37:48</datetime>
<name>Frank</name>
<email>frank#gmail.com</email>
<address/>
<region>BC</region>
<country>IN</country>
<zip_postal>V8V1J9</zip_postal>
<phone_number>1231231234</phone_number>
<language>EN</language>
<ip>209.13.233.227</ip>
<currency>CAD</currency>
</customer>
</order>
Yup as stated use simplexml_load_file($url) ; to parse xml.
you can find examples here : http://www.w3schools.com/php/php_xml_simplexml_get.asp
Make a correction in original string with something like this:
<?php
$xml_file = 'vendorOrder.log';
$xml_content = file_get_contents( $xml_file );
$xml_content .= "\n</order>";
$xml_content = substr( $xml_content, 20 );
var_dump($xml_content);
$xml=simplexml_load_string($xml_content) or die("Error: Cannot create object");
echo $xml->customer->name;
I am having an issue with a recursive function I am trying to work on. I have an XML file that essentially documents a file/folder structure. These XML nodes (which represent a file/folder) can be N levels deeps. So, I am trying to write a script that iterates over all the nodes and creates entries into a database. For the folders, I have a table structure that has an ID, field_name, and parent_id columns. The parent_id points to the ID of a folder the current folder resides in. If it's at the root level, the ID is 0.
My problem is that I'm not able to accurately keep track of the parent_id, when I get down lover levels, then comes back up. Here is an example of XML, but realize the folders can be any number of levels:
<XML>
<programs>
<program name ="xxx">
<groups>
<group id ="1" name ="yyy">
<folder name = "ggg">
<file name = "ddfdf"/>
<file name = "ddfdf"/>
<folder name = "sub" />
</folder>
<folder name = "sdfsdfs">
<file name = "ddfdf"/>
<folder name = "sub" >
<file name = "ddfdf"/>
</folder>
</folder>
</group>
</groups>
</program>
</programs>
</xml>
Script:
foreach($program as $p){
//creates root folder and returns ID
$id = create_folder($folder);
$rootId = $id;
$groups = $program->groups;
if($p->groups){
foreach($p->groups as $group){
foreach($group as $folder){
process_folder($folder,$id, $rootId);
}
}
}
}
function process_folder(($folder,$id, $rootId){
foreach($folder as $key=>$value){
switch ($key){
case "folder":
//creates folder, then returns the ID of the db record
$parentId = create_folder($folder);
process_folder($value, $parentId, $rootId);
//reset ID but this doesnt seem to work
$parentId = $rootId;
break;
case "file":
break;
}
}
}
This is not a complete solution but it shows how a recursiveIterator might be used to accomplish what you want to do.
$strxml='
<xml>
<programs>
<program name ="xxx">
<groups>
<group id ="1" name ="yyy">
<folder name = "ggg">
<file name = "ddfdf"/>
<file name = "ddfdf"/>
<folder name = "sub" />
</folder>
<folder name = "sdfsdfs">
<file name = "ddfdf"/>
<folder name = "sub" >
<file name = "ddfdf"/>
</folder>
</folder>
</group>
</groups>
</program>
</programs>
</xml>';
class RecursiveDOMIterator implements RecursiveIterator {
private $index;
private $list;
public function __construct(DOMNode $domNode){
$this->index = 0;
$this->list = $domNode->childNodes;
}
public function current(){
return $this->list->item($this->index);
}
public function getChildren(){
return new self( $this->current() );
}
public function hasChildren(){
return $this->current()->hasChildNodes();
}
public function key(){
return $this->index;
}
public function next(){
$this->index++;
}
public function rewind(){
$this->index = 0;
}
public function valid(){
return $this->index < $this->list->length;
}
}
$xml=new DOMDocument;
$xml->loadXML( $strxml );
$rootnode=$xml->getElementsByTagName('programs')->item(0);
$nodeItr=new RecursiveDOMIterator( $rootnode );
$itr=new RecursiveIteratorIterator( $nodeItr, RecursiveIteratorIterator::SELF_FIRST );
foreach( $itr as $node ) {
if( $node->nodeType === XML_ELEMENT_NODE ) {
$id=$node->hasAttribute('id') ? $node->getAttribute('id') : false;
$attr=$node->hasAttribute('name') ? $node->getAttribute('name') : false;
echo $id.' '.$node->nodeName . ' ' . $node->nodeValue. ' ' . $attr .' '.$node->parentNode->tagName . ' ' . '<br />';
}
}
$dom=$rootnode=$itr=$nodeItr=null;
Consider using XSLT to simplify your XML to a one child level format. Then run a simple PHP loop to extract parent id and folder data for database migration. In fact, if using MySQL you can import this exact transformed XML document into database with LoadXML(), should node names match column names.
As information, XSLT is a special-purpose, declarative programming language (same type as SQL) used to re-structure XML documents to various structures for end use needs. Like all general purpose languages including C#, Java, Python, Perl, VB, PHP maintains an XSLT processor. Below is an XSLT script (which you can add to for each nest in XML document) and PHP script (to transform and iterate through output).
XSLT Script (save as .xsl or .xslt)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="*"/>
</root>
</xsl:template>
<xsl:template match="folder" name="foldertemplate">
<row>
<parent_id>0</parent_id>
<field_name><xsl:value-of select="#name"/></field_name>
</row>
<!-- ADD LEVELS FOR EACH NEST IN XML DOCUMENT -->
<row>
<parent_id><xsl:value-of select="#name"/></parent_id>
<field_name><xsl:value-of select="folder/#name"/></field_name>
</row>
<!-- EXAMPLE NEXT LEVEL -->
<!-- <row> -->
<!-- <parent_id><xsl:value-of select="folder/#name"/></parent_id> -->
<!-- <field_name><xsl:value-of select="folder/folder/#name"/></field_name> -->
<!-- </row> -->
</xsl:template>
</xsl:transform>
TRANSFORMED XML OUTPUT (easier to parse and iterate over)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<parent_id>0</parent_id>
<field_name>ggg</field_name>
</row>
<row>
<parent_id>ggg</parent_id>
<field_name>sub</field_name>
</row>
<row>
<parent_id>0</parent_id>
<field_name>sdfsdfs</field_name>
</row>
<row>
<parent_id>sdfsdfs</parent_id>
<field_name>sub</field_name>
</row>
</root>
PHP Script (to transform and loop through output)
// Set current directory
$cd = dirname(__FILE__);
// Load the XML source and XSLT file
$doc = new DOMDocument();
$doc->load($cd.'/Input.xml');
$xsl = new DOMDocument;
$xsl->load($cd.'/XSLTScript.xsl');
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXml = $proc->transformToXML($doc);
// Save output to file
$xmlfile = $cd.'/Output.xml';
file_put_contents($xmlfile, $newXml);
// Load new XML with SimpleXML
$newdoc = simplexml_load_file($cd.'/Output.xml');
$data = [];
$node = $newdoc->xpath('//row');
$parents = $newdoc->xpath('//row/parent_id');
$folders = $newdoc->xpath('//row/field_name');
// Loop through folder names and parent
for($i=0; $i < sizeof($node); $i++) {
echo 'parent: '.$parents[$i]. ' folder: ' . $folders[$i]."\n";
}
#parent: 0 folder: ggg
#parent: ggg folder: sub
#parent: 0 folder: sdfsdfs
#parent: sdfsdfs folder: sub
I am trying to loop through a set of records in an XML document, but cannot access subnodes that are in other namespaces.
this is my php code:
$xml = new SimpleXMLElement($xml);
$ns = $xml->getNamespaces(true);
$xml->registerXPathNamespace('ns', $ns['']);
$xmlRecords = $xml->xpath('//ns:recordData');
foreach ($xmlRecords as $record)
{
$enrichedData = $record->gzd->enrichedData; //Yes! Works!
$originalData = $record->gzd->originalData; //empty
}
The problem is that $orginalData remains empty, probably because al the subnodes inside node originalData belong to other namespaces. My question is: how do I get these subnodes available in my records loop? I need all the nodes that are under the dcterms namespace.
Here is the source xml:
<?xml version="1.0" encoding="UTF-8"?>
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/zing/srw/ srw-types.xsd">
<version>1.2</version>
<numberOfRecords>23</numberOfRecords>
<records>
<record>
<recordSchema>http://standaarden.overheid.nl/sru/</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<gzd xmlns="http://standaarden.overheid.nl/sru" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidrg="http://standaarden.overheid.nl/cvdr/terms/" xsi:schemaLocation="http://standaarden.overheid.nl/sru gzd.xsd">
<originalData>
<overheidrg:meta>
<owmskern>
<dcterms:identifier>123431_2</dcterms:identifier>
<dcterms:title>Ligplaatsenverordening 2009</dcterms:title>
<dcterms:language>nl</dcterms:language>
<dcterms:type scheme="overheid:Informatietype">regeling</dcterms:type>
<dcterms:creator scheme="overheid:Gemeente">Muiden</dcterms:creator>
<dcterms:modified>2015-08-27</dcterms:modified>
</owmskern>
<owmsmantel>
<dcterms:isFormatOf resourceIdentifier="">Onbekend</dcterms:isFormatOf>
<dcterms:alternative>Ligplaatsenverordening 2009</dcterms:alternative>
<dcterms:source resourceIdentifier="">artikel 149 van de Gemeentewet</dcterms:source>
<dcterms:isRatifiedBy scheme="overheid:BestuursorgaanGemeente">gemeenteraad</dcterms:isRatifiedBy>
<dcterms:subject>ruimtelijke ordening, verkeer en vervoer</dcterms:subject>
<dcterms:issued>2012-12-20</dcterms:issued>
</owmsmantel>
<cvdripm>
<overheidrg:inwerkingtredingDatum>2013-01-01</overheidrg:inwerkingtredingDatum>
<overheidrg:uitwerkingtredingDatum />
<overheidrg:betreft>Onbekend</overheidrg:betreft>
<overheidrg:kenmerk>Onbekend</overheidrg:kenmerk>
<overheidrg:onderwerp />
<overheidrg:gedelegeerdeRegelgeving><al >Geen</al></overheidrg:gedelegeerdeRegelgeving>
<overheidrg:redactioneleToevoeging><al >Geen</al></overheidrg:redactioneleToevoeging>
</cvdripm>
</overheidrg:meta>
</originalData>
<enrichedData>
<organisatietype>Gemeente</organisatietype>
<publicatieurl_xhtml>http://decentrale.regelgeving.overheid.nl/cvdr/xhtmloutput/Historie/Muiden/123431/123431_2.html</publicatieurl_xhtml>
<publicatieurl_xml>http://decentrale.regelgeving.overheid.nl/cvdr/xmloutput/Historie/Muiden/123431/123431_2.xml</publicatieurl_xml>
</enrichedData>
</gzd>
</recordData>
<recordPosition>1</recordPosition>
</record>
</records>
</searchRetrieveResponse>
You can use the SimpleXMLElement children method with the corresponding namespaces like children($ns['overheidrg']) and children($ns['dcterms']).
For example:
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/zing/srw/ srw-types.xsd">
<version>1.2</version>
<numberOfRecords>23</numberOfRecords>
<records>
<record>
<recordSchema>http://standaarden.overheid.nl/sru/</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<gzd xmlns="http://standaarden.overheid.nl/sru" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:overheid="http://standaarden.overheid.nl/owms/terms/" xmlns:overheidrg="http://standaarden.overheid.nl/cvdr/terms/" xsi:schemaLocation="http://standaarden.overheid.nl/sru gzd.xsd">
<originalData>
<overheidrg:meta>
<owmskern>
<dcterms:identifier>123431_2</dcterms:identifier>
<dcterms:title>Ligplaatsenverordening 2009</dcterms:title>
<dcterms:language>nl</dcterms:language>
<dcterms:type scheme="overheid:Informatietype">regeling</dcterms:type>
<dcterms:creator scheme="overheid:Gemeente">Muiden</dcterms:creator>
<dcterms:modified>2015-08-27</dcterms:modified>
</owmskern>
<owmsmantel>
<dcterms:isFormatOf resourceIdentifier="">Onbekend</dcterms:isFormatOf>
<dcterms:alternative>Ligplaatsenverordening 2009</dcterms:alternative>
<dcterms:source resourceIdentifier="">artikel 149 van de Gemeentewet</dcterms:source>
<dcterms:isRatifiedBy scheme="overheid:BestuursorgaanGemeente">gemeenteraad</dcterms:isRatifiedBy>
<dcterms:subject>ruimtelijke ordening, verkeer en vervoer</dcterms:subject>
<dcterms:issued>2012-12-20</dcterms:issued>
</owmsmantel>
<cvdripm>
<overheidrg:inwerkingtredingDatum>2013-01-01</overheidrg:inwerkingtredingDatum>
<overheidrg:uitwerkingtredingDatum />
<overheidrg:betreft>Onbekend</overheidrg:betreft>
<overheidrg:kenmerk>Onbekend</overheidrg:kenmerk>
<overheidrg:onderwerp />
<overheidrg:gedelegeerdeRegelgeving><al >Geen</al></overheidrg:gedelegeerdeRegelgeving>
<overheidrg:redactioneleToevoeging><al >Geen</al></overheidrg:redactioneleToevoeging>
</cvdripm>
</overheidrg:meta>
</originalData>
<enrichedData>
<organisatietype>Gemeente</organisatietype>
<publicatieurl_xhtml>http://decentrale.regelgeving.overheid.nl/cvdr/xhtmloutput/Historie/Muiden/123431/123431_2.html</publicatieurl_xhtml>
<publicatieurl_xml>http://decentrale.regelgeving.overheid.nl/cvdr/xmloutput/Historie/Muiden/123431/123431_2.xml</publicatieurl_xml>
</enrichedData>
</gzd>
</recordData>
<recordPosition>1</recordPosition>
</record>
</records>
</searchRetrieveResponse>
XML;
$xml = new SimpleXMLElement($xml);
$ns = $xml->getNamespaces(true);
$xml->registerXPathNamespace('ns', $ns['']);
$xmlRecords = $xml->xpath('//ns:recordData');
foreach ($xmlRecords as $record)
{
$enrichedData = $record->gzd->enrichedData; //Yes! Works!
$originalData = $record
->gzd
->originalData
->children($ns['overheidrg'])
->meta
->children();
foreach ($originalData as $originalDataItem) {
// Get the children using the namespace 'dcterms'
$children = $originalDataItem->children($ns['dcterms']);
// Check for the name of the xml element
if ($originalDataItem->getName() === "owmskern") {
$identifier = $children->identifier->__toString();
// etc...
}
if ($originalDataItem->getName() === "owmsmantel") {
$isFormatOf = $children->isFormatOf->__toString();
// etc...
}
}
}
I am working on an application that will make a KML file with PHP. Typically I have done this with single points and had no or little problem, but for polygons I'm having one heck of a hard time getting them to stylize.
What I am attempting to do is colorize a polygon shape based on a dynamic style from PHP; however, I can't even get a hard-coded style to work first. The structure of the KML is shown after the code sample I'm having problems with.
What should the proper style dom syntax look like if all I want to do is setup a polygon color style and a certain width.
Thanks for your help
Here is the initial code:
// Creates the Document.
$dom = new DOMDocument('1.0', 'UTF-8');
$kmlfile = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml');
$parentnode = $dom->appendChild($kmlfile);
$dfnode = $dom->createElement('Document');
$documentnode = $parentnode->appendChild($dfnode);
$gpsStyleNode = $dom->createElement('Style');
$gpsStyleNode->setAttribute('id', 'style_gps');
$gpsIconstyleNode = $dom->createElement('IconStyle');
$gpsIconstyleNode->setAttribute('id', 'icon_gps');
$gpsIconstyleNode->setAttribute('scale', '0.6');
$gpsIconstyleNode->setAttribute('color', 'ff0000ff');
$gpsIconNode = $dom->createElement('Icon');
$gpsHref = $dom->createElement('href', 'http://maps.google.com/mapfiles/kml/shapes/cross-hairs.png');
$gpsIconNode->appendChild($gpsHref);
$gpsIconstyleNode->appendChild($gpsIconNode);
$gpsStyleNode->appendChild($gpsIconstyleNode);
$gpslinetyleNode = $dom->createElement('PolyStyle');
$gpsStyleNode->appendChild($gpslinetyleNode);
$gpslinetyleNode->setAttribute('id', 'Icon_gps2');
$gpslinetyleNode->setAttribute('color', 'ff0000ff');
$gpslinetyleNode->setAttribute('width', '20');
$documentnode->appendChild($gpsStyleNode);
KML Output
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Placemark id="12">
<name>PolygonName</name>
<description>test</description>
<styleUrl>Icon_gps2</styleUrl>
<Polygon>
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates>
(Dynamic Coords pulled from DB in proper format)
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</kml>
EDIT to add Polygon Code
$placeobject = $dom->createElement('Placemark');
$placeNode = $nDoc->appendChild($placeobject);
$placeobject->setAttribute('id',$tmpid);
$placename = $dom->createElement('name','PolygonName');
$placeNode->appendChild($placename);
$placedesc = $dom->createElement('description', 'test');
$placeNode->appendChild($placedesc);
$stylenode =$dom->createElement('styleUrl','line_gps');
$placeNode->appendChild($stylenode);
$linenode = $dom->createElement('Polygon');
$placeNode->appendChild($linenode);
$lineextrude = $dom->createElement('extrude', '1');
$linenode->appendChild($lineextrude);
$linealtitude = $dom->createElement('altitudeMode', 'relativeToGround');
$linenode->appendChild($linealtitude);
$outerboundnode = $dom->createElement('outerBoundaryIs');
$linenode = $linenode->appendChild($outerboundnode);
$ringtype =$dom->createElement('LinearRing');
$linenode = $linenode->appendChild($ringtype);
$coordnode = $dom->createElement('coordinates',$locationstring);
$ringtype->appendChild($coordnode);
Your are setting attributes(color,scale,width) which are expected as elements.
Furthermore width applies to LineStyle and not to PolyStyle
$dom = new DOMDocument('1.0', 'UTF-8');
$nKml = $dom->appendChild($dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'));
$nDoc = $nKml->appendChild($dom->createElement('Document'));
$idSuffix='_gps';
//Style
$nStyle = $nDoc->appendChild($dom->createElement('Style'));
$nStyle->setAttribute('id', 'style'.$idSuffix);
//IconStyle
$nIconStyle = $nStyle->appendChild($dom->createElement('IconStyle'));
$nIconStyle->setAttribute('id', 'icon'.$idSuffix);
//color
$nIconStyleColor=$nIconStyle->appendChild($dom->createElement('color'));
$nIconStyleColor->appendChild($dom->createTextNode('ff0000ff'));
//Icon
$nIconStyleIcon=$nIconStyle->appendChild($dom->createElement('Icon'));
//href
$nIconStyleHref=$nIconStyleIcon->appendChild($dom->createElement('href'));
$nIconStyleHref->appendChild($dom->createTextNode('http://maps.google.com/../cross-hairs.png'));
//PolyStyle
$nPolyStyle = $nStyle->appendChild($dom->createElement('PolyStyle'));
$nPolyStyle->setAttribute('id', 'poly'.$idSuffix);
//color
$nPolyStyleColor=$nPolyStyle->appendChild($dom->createElement('color'));
$nPolyStyleColor->appendChild($dom->createTextNode('ff0000ff'));
//LineStyle
$nLineStyle = $nStyle->appendChild($dom->createElement('LineStyle'));
$nLineStyle->setAttribute('id', 'line'.$idSuffix);
//width
$nLineStyleWidth=$nLineStyle->appendChild($dom->createElement('width'));
$nLineStyleWidth->appendChild($dom->createTextNode('20'));
$nLineStyleColor=$nLineStyle->appendChild($dom->createElement('color'));
$nLineStyleColor->appendChild($dom->createTextNode('ff0000ff'));
result:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<Style id="style_gps">
<IconStyle id="icon_gps">
<color>ff0000ff</color>
<Icon>
<href>http://maps.google.com/../cross-hairs.png</href>
</Icon>
</IconStyle>
<PolyStyle id="poly_gps">
<color>ff0000ff</color>
</PolyStyle>
<LineStyle id="line_gps">
<width>20</width>
<color>ff0000ff</color>
</LineStyle>
</Style>
</Document>
</kml>