Search code examples
phpxmlxpathsimplexml

Iterating through XML with SimpleXML and XPath, Result is in wrong order


my variables.php

$xmlFile = 'xml.xml';
$xmlFileLoad = simplexml_load_file($xmlFile);
$xmlFileLoad->registerXPathNamespace("oi", "http://www.openimmo.de");
$immobilie = $xmlFileLoad->xpath('//oi:immobilie');

$zustand_angaben_letztemodernisierung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:letztemodernisierung');
$zustand_angaben_zustand = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:zustand/@zustand_art');
$zustand_angaben_alter = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:alter/@alter_attr');
$zustand_angaben_erschliessung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:erschliessung/@erschl_attr');
$zustand_angaben_altlasten = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:altlasten');
$zustand_angaben_baujahr = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:baujahr');

the xml file (shorted version)

<?xml version="1.0" encoding="utf-8"?>
<openimmo xmlns="http://www.openimmo.de"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.openimmo.de openimmo.xsd">
    <immobilie>
        <zustand_angaben>
            <altlasten>keine</altlasten>
        </zustand_angaben>
    </immobilie>
    <immobilie>
        <zustand_angaben>
            <altlasten>keine</altlasten>
        </zustand_angaben>
    </immobilie>
    <immobilie>
        <zustand_angaben>
            <altlasten>keine</altlasten>
        </zustand_angaben>
    </immobilie>
    <immobilie>
        <zustand_angaben>
            <baujahr>ca. 1900</baujahr>
            <altlasten>nein</altlasten>
        </zustand_angaben>
    </immobilie>
    <immobilie>
        <zustand_angaben>
            <baujahr>ca. 1989</baujahr>
            <zustand zustand_art="ERSTBEZUG" />
            <alter alter_attr="ALTBAU" />
            <altlasten>keine</altlasten>
        </zustand_angaben>
    </immobilie>
</openimmo>

my show.php

<?php
    include("variables.php");

    $i = 0;
    foreach ($immobilie as $immo) {

        echo "Immobilie $i<br />";
        if(isset($zustand_angaben_zustand[$i])) {
            echo $zustand_angaben_zustand[$i] . "</br>";
        }

        if(isset($zustand_angaben_alter[$i])) {
            echo $zustand_angaben_alter[$i] . "</br>";
        }

        if(isset($zustand_angaben_erschliessung[$i])) {
            echo $zustand_angaben_erschliessung[$i] . "</br>";
        }

        if(isset($zustand_angaben_altlasten[$i])) {
            echo $zustand_angaben_altlasten[$i] . "</br>";
        }

        if(isset($zustand_angaben_baujahr[$i])) {
            echo $zustand_angaben_baujahr[$i] . "</br>";
        }   
        echo "<br /><br />";
        $i++;
    }
?>

when i'm executing the code, the result will be the following

Immobilie 0
ERSTBEZUG
ALTBAU
keine
5
A
5
A++
ca. 1900

Immobilie 1
keine

ca. 1989

Immobilie 2
keine

Immobilie 3
nein

Immobilie 4
keine

but i want it in the order like in the xml, so Immobilie 0 has only keine, Immobilie 1 and 2 too, the third 1900 and nein and last but not least Immobilie 4 with all the properties in the xml...

what am i doing wrong?


Solution

  • Use XPath expressions that relative to current immobilie element instead :

    $i = 0;
    foreach ($immobilie as $immo) {
        $immo->registerXPathNamespace("oi", "http://www.openimmo.de");
        $zustand_angaben_letztemodernisierung = $immo->xpath('./oi:zustand_angaben/oi:letztemodernisierung');
        $zustand_angaben_zustand = $immo->xpath('./oi:zustand_angaben/oi:zustand/@zustand_art');
        $zustand_angaben_alter = $immo->xpath('./oi:zustand_angaben/oi:alter/@alter_attr');
        $zustand_angaben_erschliessung = $immo->xpath('./oi:zustand_angaben/oi:erschliessung/@erschl_attr');
        $zustand_angaben_altlasten = $immo->xpath('./oi:zustand_angaben/oi:altlasten');
        $zustand_angaben_baujahr = $immo->xpath('./oi:zustand_angaben/oi:baujahr');
    
        echo "Immobilie $i<br />";
        if(isset($zustand_angaben_zustand[0])) {
            echo $zustand_angaben_zustand[0] . "</br>";
        }
    
        if(isset($zustand_angaben_alter[0])) {
            echo $zustand_angaben_alter[0] . "</br>";
        }
    
        if(isset($zustand_angaben_erschliessung[0])) {
            echo $zustand_angaben_erschliessung[0] . "</br>";
        }
    
        if(isset($zustand_angaben_altlasten[0])) {
            echo $zustand_angaben_altlasten[0] . "</br>";
        }
    
        if(isset($zustand_angaben_baujahr[0])) {
            echo $zustand_angaben_baujahr[0] . "</br>";
        }   
        echo "<br /><br />";
        $i++;
    }
    

    eval.in demo