SimpleXML: Unterschied zwischen den Versionen
| Zeile 262: | Zeile 262: | ||
===Beispiel Mobile de=== | ===Beispiel Mobile de=== | ||
<pre> | <pre> | ||
| + | |||
| + | <?php | ||
| + | |||
| + | class Mobile{ | ||
| + | var $arrNs = array(); | ||
| + | |||
| + | public function init(){ | ||
| + | $this->action = ""; | ||
| + | $this->user = "username"; | ||
| + | $this->pw = "passwort"; | ||
| + | $this->customerId = "461731"; | ||
| + | $this->clientId = "517329"; | ||
| + | $this->baseUrl = "services.mobile.de/1.0.0/ad/search"; | ||
| + | $arrResult = array(); // Contains last Result-List | ||
| + | } | ||
| + | |||
| + | public function main(){ | ||
| + | $this->init(); | ||
| + | //echo("<strong>loadVehicles</strong><br>"); | ||
| + | $params = "?customerId=".$this->customerId."&page.size=100"; | ||
| + | $url = $this->baseUrl.$params; | ||
| + | |||
| + | $this->sxe = $this->fetch_xml_data_ctx($url); | ||
| + | $this->register_namespaces(); | ||
| + | $this->parseXML($this->sxe); | ||
| + | //$this->sxe_print_info(); | ||
| + | $this->send_json($this->arrResult); | ||
| + | } | ||
| + | |||
| + | //Parse XML and create Array | ||
| + | private function parseXML($sxe){ | ||
| + | $arrAds = array(); | ||
| + | unset($this->arrResult); | ||
| + | // ADS | ||
| + | $xpath='//ad:ad'; | ||
| + | $result = $sxe->xpath($xpath); | ||
| + | $count = 0; | ||
| + | if(count($result) > 0){ | ||
| + | foreach ($result as $ad) { | ||
| + | // AUTO Parsing | ||
| + | $this->arrResult[ad][$count] = $this->sxe_to_array($ad,'ad'); | ||
| + | |||
| + | // MANUAL Parsing | ||
| + | // Images | ||
| + | unset($arrImages); | ||
| + | $arrRepresentation = $ad->xpath('ad:images/ad:image/ad:representation'); | ||
| + | foreach($arrRepresentation as $representation){ | ||
| + | foreach($representation->attributes() as $key=>$val){ | ||
| + | $arrImages[$key][]=(string)$val; | ||
| + | } | ||
| + | } | ||
| + | $this->arrResult[ad][$count]['images']= $arrImages; | ||
| + | $count += 1; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // Stores Attributes and Childs into Array | ||
| + | private function sxe_to_array(SimpleXMLElement $sxe,$ns){ | ||
| + | $arr = array(); | ||
| + | // ATTRIBUTES | ||
| + | $count=0; | ||
| + | foreach( $sxe->attributes() as $attr_name => $attr_value ){ | ||
| + | $arr['attributes'][(string)$attr_name] = (string)$attr_value; | ||
| + | } | ||
| + | |||
| + | // CHILDREN | ||
| + | $children = $sxe->children($ns,TRUE); | ||
| + | $count = 0; | ||
| + | foreach($children as $child_name=>$child_node){ | ||
| + | $arrChild = $this->sxe_to_array($child_node,$ns); | ||
| + | // RESSOURCE CHILD (ns resource) | ||
| + | $resources = $this->getResources($child_node); | ||
| + | //print_r($resources); | ||
| + | if(!empty($resources)) $arrChild['resources'] = $resources; | ||
| + | $arr['children'][$count][$child_name]['value']=(string)$child_node; | ||
| + | $arr['children'][$count][$child_name] = $arrChild; | ||
| + | } | ||
| + | |||
| + | //echo("</pre>"); | ||
| + | return $arr; | ||
| + | |||
| + | } | ||
| + | |||
| + | private function getResources($node){ | ||
| + | //add 'resource' namespace children (mobilede uses this as language descriptors) | ||
| + | $count = 0; | ||
| + | $ns="resource"; | ||
| + | $arr = array(); | ||
| + | $children = $node->children($ns,TRUE); | ||
| + | foreach($children as $resource_name=>$resource_node){ | ||
| + | //print_r($resource_node); | ||
| + | $arrResource = $this->sxe_to_array($resource_node,$ns); | ||
| + | $arr[$count][$resource_name]['value']=(string)$resource_node; | ||
| + | //echo((string)$resource_node); | ||
| + | //$arr[$count][$resource_name] = $arrResource; | ||
| + | $count +=1; | ||
| + | } | ||
| + | return $arr; | ||
| + | } | ||
| + | |||
| + | |||
| + | private function sxe_print_info(){ | ||
| + | $sxe = $this->sxe; | ||
| + | $namespaces = $sxe->getNamespaces(true); | ||
| + | echo("<br>##########<br><strong>namespaces:</strong> <br>"); | ||
| + | foreach($namespaces as $key=>$val){ | ||
| + | //echo("$key : $val<br>"); | ||
| + | } | ||
| + | echo("<br>Name: ".$sxe->getName()."<br>"); | ||
| + | //Print Ads Info | ||
| + | $xpath='//ad:ad'; | ||
| + | $result = $this->sxe->xpath($xpath); | ||
| + | //echo("Number of ads: ".count($result)."<br><br>"); | ||
| + | $count = 0; | ||
| + | //ADs | ||
| + | foreach ($result as $ad) { | ||
| + | $count += 1; | ||
| + | echo("<strong>Ad $count </strong><br>"); | ||
| + | $ad_children = $ad->children('ad',TRUE); | ||
| + | //AD 1st Gen Children | ||
| + | if(count($ad_children) > 0){ | ||
| + | foreach ($ad_children as $ad_child_name=>$ad_child_node){ | ||
| + | echo("<strong>Childname: $ad_child_name</strong><br>"); | ||
| + | // ATTRIBUTES | ||
| + | foreach($ad_child_node->attributes() as $key=>$val){ | ||
| + | echo("<strong>Attributes:</strong> "); | ||
| + | echo("$key=$val<br>"); | ||
| + | echo("<strong>Children: </strong><br>"); | ||
| + | // Ad 2nd Gen Children | ||
| + | foreach($ad_child_node->children() as $ad_child_name=>$child_node){ | ||
| + | echo("Name: $child_name<br>"); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | //$adurl = $ad->{'detail-page'}->value->attributes()->url; | ||
| + | //echo('<a href="'.$adurl.'" target="_blank">Link</a><br>'); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function register_namespaces(){ | ||
| + | $this->arrNs = $this->sxe->getNamespaces(true); | ||
| + | foreach($this->arrNs as $prefix => $ns){ | ||
| + | $this->sxe->registerXPathNamespace($prefix, $ns); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function fetch_xml_data_ctx($url){ | ||
| + | // Erzeugen eines Streams | ||
| + | $headers = "Accept-language: de\r\n"; | ||
| + | $headers .= "Accept: application/xml\r\n"; | ||
| + | $headers .= "Authorization: Basic ".base64_encode("$this->user:$this->pw")."\r\n"; | ||
| + | $opts = array( | ||
| + | 'http'=>array( | ||
| + | 'method'=>"GET", | ||
| + | 'header'=> $headers | ||
| + | |||
| + | ) | ||
| + | ); | ||
| + | $context = stream_context_create($opts); | ||
| + | // Öffnen der Datei mit den oben definierten HTTP-Headern | ||
| + | $file = file_get_contents('https://'.$url, false, $context); | ||
| + | $simplexml=simplexml_load_string($file); | ||
| + | //print_r($file); | ||
| + | |||
| + | return $simplexml; | ||
| + | |||
| + | } | ||
| + | |||
| + | function send_json($arrJSON){ | ||
| + | // Wir geben der Anfrage ein JSON Objekt-Literal zurück | ||
| + | $ajax_return_data = json_encode($arrJSON); | ||
| + | header('Cache-Control: no-cache, must-revalidate'); | ||
| + | header('Pragma: no-cache'); | ||
| + | header('Content-Length: '.strlen($ajax_return_data)); | ||
| + | header('Content-Type: application/json; charset=UTF-8'); | ||
| + | echo $ajax_return_data; | ||
| + | exit; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | $mobile = new Mobile(); | ||
| + | $mobile->main(); | ||
| + | ?> | ||
</pre> | </pre> | ||
Version vom 19. Juli 2013, 13:46 Uhr
Simple XML ist eine PHP Schnittstelle zum Parsen von XML Dateien.
Einführung
Generelles vorgehen
- Einlesen der Daten (z.B. XML-Datei, oder String) in ein SimpleXML Objekt
- xpath Query auf das Objekt anwenden ($result= $sxe->xpath("Pfadangabe"). Man erhält ein Array mit SimpleXML Objekten
- Zugriff auf Werte und Attribute der simpleXML Objekte.
- auf Elemente
SimpleXML 101 - Empfehlungen zur Arbeit mit simpleXML
Quelle: http://stackoverflow.com/questions/1893024/basic-simplexml-working-example Zugriff 7/2013
Example:
<?xml version="1.0" encoding="ISO-8859-1"?> <programme> <title>Billy Bushwaka</title> <episodeNumber>2</episodeNumber> <description>Billy Bushwaka entertains</description> <url>play.swf</url> </programme>
First of all, always name your PHP variables after the node they represent.
// the root node is ie <programme/>
$programme = simplexml_load_file("local.xml");
Access to children (nodes) as if they were object properties.
echo $programme->title;
If there are multiple children using the same name, you can specify their 0-based position
// first <title/> child echo $programme->title[0];
// create or change the value of the second <title/> child $programme->title[1] = 'Second title';
Access to attributes as if they were array keys
// <mynode attr="attribute value" /> echo $mynode['attr'];
XPath always returns an array.
More Hints
Quick XML
$string = <<<XML <a> <foo name="one" game="lonely">1</foo> </a> XML;
Alternative xpath:
$result = $xml->xpath("//programme/title");
Quellcode der xml Datei ausgeben
echo $simplexml->asXML();
XML Daten von URL holen
$url = "http://username:password@url.com"; $xml = file_get_contents($url); $data = new SimpleXMLElement($xml);
Snippets
XML-Datei einlesen und in SimpleXML Objekt speichern
//einfache Variante
function fetch_xml_data($url){
$simplexml=simplexml_load_file(rawurlencode("https://".$this->user.":".$this->pw.'@'.$url));
$simplexml=simplexml_load_file("test.xml");
return $simplexml;
}
// Variante - Einlesen mit Context um diverse Header mit zu schicken
function fetch_xml_data_ctx($url){
// Erzeugen eines Streams
$headers = "Accept-language: de\r\n";
$headers .= "Accept: application/xml\r\n";
$headers .= "Authorization: Basic ".base64_encode("$this->user:$this->pw")."\r\n";
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=> $headers
)
);
$context = stream_context_create($opts);
// Öffnen der Datei mit den oben definierten HTTP-Headern
$file = file_get_contents('https://'.$url, false, $context);
$simplexml=simplexml_load_string($file);
//print_r($file);
return $simplexml;
}
Zugriff auf Werte
xPath
<?php
$string = <<<XML
<a>
<b>
<c>text</c>
<c>stuff</c>
</b>
<d>
<c>code</c>
</d>
</a>
XML;
$xml = new SimpleXMLElement($string);
/* Search for <a><b><c> */
$result = $xml->xpath('/a/b/c');
while(list( , $node) = each($result)) {
echo '/a/b/c: ',$node,"\n";
}
/* Relative paths also work... */
$result = $xml->xpath('b/c');
while(list( , $node) = each($result)) {
echo 'b/c: ',$node,"\n";
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
/a/b/c: text /a/b/c: stuff b/c: text b/c: stuff
Zugriff auf Attribute
Beispiel 1
Man lädt mittels foreach alle Attribute des SimpleXML Objektes in ein Array und greift dann darüber zu.
foreach( $sxe->attributes() as $attr_name => $attr_value ){
$arr['attributes'][(string)$attr_name] = (string)$attr_value;
}
Hinweis: Damit der Wert des Attributes als String ausgegeben wird muß man Casten (string) ansonsten wird ein Objekt zurück gegeben.
Beispiel 2
ein $sxe Objekt kann z.B. so aussehen (mit var_dump):
array(1) {
[0]=>
object(SimpleXMLElement)#3 (1) {
["@attributes"]=>
array(4) {
["total"]=>
string(2) "85"
["page-size"]=>
string(2) "50"
["current-page"]=>
string(1) "1"
["max-pages"]=>
string(1) "2"
}
}
}
Kindknoten abfragen
$children = $sxe->children($ns,TRUE);
$ns ist der Namespace, der zweite Parameter sagt ob rekursiv gesucht wird.
Namespaces registrieren
Über eine kleine Funktion kann man sich arbeit sparen.
function register_namespaces($sxe){
$arrNs = $sxe->getNamespaces(true);
foreach($arrNs as $prefix => $ns){
$sxe->registerXPathNamespace($prefix, $ns);
echo($prefix.' = '.$ns);
}
}
Alle im XML Dokument angegebenen Namespaces werden geparsed und Registriert. So kann man sie in Kurzform ansprechen.
SimpleXML und Namespaces
Allgemein
$xml = <<<EOD
<book xmlns:chap="http://example.org/chapter-title">
<title>My Book</title>
<chapter id="1">
<chap:title>Chapter 1</chap:title>
<para>Donec velit. ...</para>
</chapter>
<chapter id="2">
<chap:title>Chapter 2</chap:title>
<para>Lorem ipsum ...</para>
</chapter>
</book>
EOD;
$sxe = new SimpleXMLElement($xml);
// Zugriff mit Namespace Prefix
$sxe->registerXPathNamespace('c', 'http://example.org/chapter-title');
$result = $sxe->xpath('//c:title');
foreach ($result as $title) {
echo $title . "\n";
}
Direkter Zugriff im nächsen Beispiel
Beispiel Ebay Timestamp
$response = <<< XMLBLOCK
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GeteBayOfficialTimeResponse xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2005-10-28T01:01:04.668Z</Timestamp>
<Ack>Success</Ack>
<Version>429</Version>
<Build>e429_intl_Bundled_1949355_R1</Build>
</GeteBayOfficialTimeResponse>
</soapenv:Body>
</soapenv:Envelope>
XMLBLOCK;
$xml = simplexml_load_string($response);
Zugriff auf Timestamp:
echo "Time: " .
$xml->children('http://schemas.xmlsoap.org/soap/envelope/')->children('urn:ebay:apis:eBLBaseComponents')->GeteBayOfficialTimeResponse->Timestamp . "\n";
oder
$xml->children('soapenv', true)->children()->GeteBayOfficialTimeResponse->Timestamp
Beispiel Mobile de
<?php
class Mobile{
var $arrNs = array();
public function init(){
$this->action = "";
$this->user = "username";
$this->pw = "passwort";
$this->customerId = "461731";
$this->clientId = "517329";
$this->baseUrl = "services.mobile.de/1.0.0/ad/search";
$arrResult = array(); // Contains last Result-List
}
public function main(){
$this->init();
//echo("<strong>loadVehicles</strong><br>");
$params = "?customerId=".$this->customerId."&page.size=100";
$url = $this->baseUrl.$params;
$this->sxe = $this->fetch_xml_data_ctx($url);
$this->register_namespaces();
$this->parseXML($this->sxe);
//$this->sxe_print_info();
$this->send_json($this->arrResult);
}
//Parse XML and create Array
private function parseXML($sxe){
$arrAds = array();
unset($this->arrResult);
// ADS
$xpath='//ad:ad';
$result = $sxe->xpath($xpath);
$count = 0;
if(count($result) > 0){
foreach ($result as $ad) {
// AUTO Parsing
$this->arrResult[ad][$count] = $this->sxe_to_array($ad,'ad');
// MANUAL Parsing
// Images
unset($arrImages);
$arrRepresentation = $ad->xpath('ad:images/ad:image/ad:representation');
foreach($arrRepresentation as $representation){
foreach($representation->attributes() as $key=>$val){
$arrImages[$key][]=(string)$val;
}
}
$this->arrResult[ad][$count]['images']= $arrImages;
$count += 1;
}
}
}
// Stores Attributes and Childs into Array
private function sxe_to_array(SimpleXMLElement $sxe,$ns){
$arr = array();
// ATTRIBUTES
$count=0;
foreach( $sxe->attributes() as $attr_name => $attr_value ){
$arr['attributes'][(string)$attr_name] = (string)$attr_value;
}
// CHILDREN
$children = $sxe->children($ns,TRUE);
$count = 0;
foreach($children as $child_name=>$child_node){
$arrChild = $this->sxe_to_array($child_node,$ns);
// RESSOURCE CHILD (ns resource)
$resources = $this->getResources($child_node);
//print_r($resources);
if(!empty($resources)) $arrChild['resources'] = $resources;
$arr['children'][$count][$child_name]['value']=(string)$child_node;
$arr['children'][$count][$child_name] = $arrChild;
}
//echo("");
return $arr;
}
private function getResources($node){
//add 'resource' namespace children (mobilede uses this as language descriptors) $count = 0; $ns="resource"; $arr = array(); $children = $node->children($ns,TRUE); foreach($children as $resource_name=>$resource_node){ //print_r($resource_node); $arrResource = $this->sxe_to_array($resource_node,$ns); $arr[$count][$resource_name]['value']=(string)$resource_node; //echo((string)$resource_node); //$arr[$count][$resource_name] = $arrResource; $count +=1; } return $arr;
}
private function sxe_print_info(){
$sxe = $this->sxe;
$namespaces = $sxe->getNamespaces(true);
echo("
##########
namespaces:
");
foreach($namespaces as $key=>$val){
//echo("$key : $val
");
}
echo("
Name: ".$sxe->getName()."
");
//Print Ads Info
$xpath='//ad:ad';
$result = $this->sxe->xpath($xpath);
//echo("Number of ads: ".count($result)."
");
$count = 0;
//ADs
foreach ($result as $ad) {
$count += 1;
echo("Ad $count
");
$ad_children = $ad->children('ad',TRUE);
//AD 1st Gen Children
if(count($ad_children) > 0){
foreach ($ad_children as $ad_child_name=>$ad_child_node){
echo("Childname: $ad_child_name
");
// ATTRIBUTES
foreach($ad_child_node->attributes() as $key=>$val){
echo("Attributes: ");
echo("$key=$val
");
echo("Children:
");
// Ad 2nd Gen Children
foreach($ad_child_node->children() as $ad_child_name=>$child_node){
echo("Name: $child_name
");
}
}
}
}
//$adurl = $ad->{'detail-page'}->value->attributes()->url;
//echo('<a href="'.$adurl.'" target="_blank">Link</a>
');
}
}
function register_namespaces(){ $this->arrNs = $this->sxe->getNamespaces(true); foreach($this->arrNs as $prefix => $ns){ $this->sxe->registerXPathNamespace($prefix, $ns); } }
function fetch_xml_data_ctx($url){ // Erzeugen eines Streams $headers = "Accept-language: de\r\n"; $headers .= "Accept: application/xml\r\n"; $headers .= "Authorization: Basic ".base64_encode("$this->user:$this->pw")."\r\n"; $opts = array(
'http'=>array(
'method'=>"GET",
'header'=> $headers
)
); $context = stream_context_create($opts); // Öffnen der Datei mit den oben definierten HTTP-Headern $file = file_get_contents('https://'.$url, false, $context); $simplexml=simplexml_load_string($file); //print_r($file);
return $simplexml;
}
function send_json($arrJSON){ // Wir geben der Anfrage ein JSON Objekt-Literal zurück $ajax_return_data = json_encode($arrJSON); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); header('Content-Length: '.strlen($ajax_return_data)); header('Content-Type: application/json; charset=UTF-8'); echo $ajax_return_data; exit; }
} $mobile = new Mobile(); $mobile->main(); ?>