SimpleXML: Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
Zeile 280: Zeile 280:
 
public function main(){
 
public function main(){
 
$this->init();
 
$this->init();
//echo("<strong>loadVehicles</strong><br>");
 
 
$params = "?customerId=".$this->customerId."&page.size=100";
 
$params = "?customerId=".$this->customerId."&page.size=100";
 
$url = $this->baseUrl.$params;
 
$url = $this->baseUrl.$params;

Version vom 19. Juli 2013, 13:47 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();
		$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(); ?>