2017-02-24 3 views
1

Ich habe verschiedene XML-Dateien, wobei ich für jede XML-Datei alle einzelnen Tags umbenannt habe, so dass jede XML-Datei den gleichen Tag-Namen hat. Das war einfach, weil die Funktion für die XML-Datei angepasst wurde.Überprüfen, ob ein Kind existiert? - SimpleXML (PHP)

Aber im Moment des Schreibens von 7 neuen Funktionen für jede XML-Datei möchte ich jetzt prüfen, ob eine XML-Datei ein bestimmtes Kind hat oder nicht. Denn wenn ich will sagen:

foreach ($items as $item) { 
$node = dom_import_simplexml($item); 
$title = $node->getElementsByTagName('title')->item(0)->textContent; 
$price = $node->getElementsByTagName('price')->item(0)->textContent; 
$url = $node->getElementsByTagName('url')->item(0)->textContent; 
$publisher = $node->getElementsByTagName('publisher')->item(0)->textContent; 
$category = $node->getElementsByTagName('category')->item(0)->textContent; 
$platform = $node->getElementsByTagName('platform')->item(0)->textContent; 
} 

ich manchmal: PHP Notice: Trying to get property of non-object in ...

Zum Beispiel. Zwei verschiedene XML-Blätter. Ein enthält Verlag, Kategorie und Plattform, die andere nicht:

XML 1:

<products> 
    <product> 
    <desc>This is a Test</desc> 
    <price>11.69</price> 
    <price_base>12.99</price_base> 
    <publisher>Stackoverflow</publisher> 
    <category>PHP</category> 
    </packshot> 
    <title>Check if child exists? - SimpleXML (PHP)</title> 
    <url>http://stackoverflow.com/questions/ask</url> 
    </product> 
</products> 

XML 2:

<products> 
    <product> 
    <image></image> 
    <title>Questions</title> 
    <price>23,90</price> 
    <url>google.de/url> 
    <platform>Stackoverflow</platform> 
    </product> 
</products> 

Sie sehen, manchmal eine XML-Datei enthält Verlag, Kategorie und Plattform aber manchmal nicht. Es könnte aber auch sein, dass nicht jeder Knoten einer XML-Datei alle Attribute wie im ersten enthält!

Also muss ich für jeden Knoten einer XML-Datei individuell prüfen, ob der Knoten Herausgeber, Kategorie oder/und Plattform enthält.

Wie kann ich das mit SimpleXML? Ich dachte über Switch-Fall, aber zuerst muss ich überprüfen, welche Childs in jedem Knoten enthalten sind.

EDIT: Vielleicht habe ich eine Lösung gefunden. Ist das eine Lösung oder nicht?

if($node->getElementsByTagName('platform')->item(0)){ 
     echo $node->getElementsByTagName('platform')->item(0)->textContent . "\n"; 
    } 

Grüße und Danke!

+0

Sie tun können, 'if (isset ($ node-> getElementsByTagName ('Verlag ') -> item)) 'und' if (is_array ($ node-> getElementsByTagName (' publisher ') -> item))' validiere – JustOnUnderMillions

+0

Aber du solltest 'simplexml' direkt verwenden. – JustOnUnderMillions

+0

Mögliches Duplikat von [php SimpleXML prüfen, ob ein Kind existiert] (http://stackoverflow.com/questions/1560827/php-simplexml-check-if-a-child-exists) –

Antwort

0

Ein Weg nach Rom ... (Arbeitsbeispiel)

$xml = "<products> 
    <product> 
    <desc>This is a Test</desc> 
    <price>11.69</price> 
    <price_base>12.99</price_base> 
    <publisher>Stackoverflow</publisher> 
    <category>PHP</category> 
    <title>Check if child exists? - SimpleXML (PHP)</title> 
    <url>http://stackoverflow.com/questions/ask</url> 
    </product> 
</products>"; 
$xml = simplexml_load_string($xml); 
#set fields to look for 
foreach(['desc','title','price','publisher','category','platform','image','whatever'] as $path){ 
     #get the first node 
     $result = $xml->xpath("product/{$path}[1]"); 
     #validate and set 
     $coll[$path] = $result?(string)$result[0]:null; 
     #if you need here a local variable do (2 x $) 
     ${$path} = $coll[$path]; 
} 
#here i do array_filter() to remove all NULL entries 
print_r(array_filter($coll)); 
#if local variables needed do 
extract($coll);#this creates $desc, $price 

Hinweis </packshot> ist ein ungültiger Knoten, hier entfernt.

XPath-Syntax https://www.w3schools.com/xmL/xpath_syntax.asp

+0

Der Pfad sollte '$ xml-> xpath (" products/product/{$ path} [1] ");' sein. Oder ich liege falsch? – Jan

+0

@Jan Es ist relativ relativ ein absolutes. Absolut ist '/ a/b/c' relativ 'b/c' oder' c' alle finden hier die gleichen Daten. Passen Sie nur auf, wenn Sie ein komplexes xml haben, in dem Unterknoten oft gleich sind, da sollten Sie absolute Pfade lieber einmal statt relativ verwenden. – JustOnUnderMillions

+0

Werfen Sie einen Blick hier https://www.w3schools.com/xmL/xpath_syntax.asp – JustOnUnderMillions

0

Zum einen sind Sie Ihren Code zu verkomplizieren, indem sie mit dom_import_simplexml von SimpleXML zu DOM wechseln. Die Dinge, die Sie mit DOM tun, können in viel kürzerem Code mit SimpleXML getan werden.

Statt dessen:

$node = dom_import_simplexml($item); 
$title = $node->getElementsByTagName('title')->item(0)->textContent; 

Sie können einfach verwenden:

$title = (string)$item->title[0]; 

oder auch nur:

$title = (string)$item->title; 

Um zu verstehen, warum das funktioniert, werfen Sie einen Blick auf the SimpleXML examples in the manual.

Bewaffnet mit diesem Wissen, werden Sie erstaunt sein, wie einfach es ist, zu sehen, ob ein Kind oder nicht vorhanden ist:

if (isset($item->title)) { 
    $title = (string)$item->title; 
} else { 
    echo "There is no title!"; 
} 
Verwandte Themen