Schleife zum befüllen eines Array für Übergabe an json-String


Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

BIM-T

Mitglied
Hallo, danke noch einmal für die rege Unterstützung in diesem Forum! :)

Ich habe folgende Aufgabe, die mir die letzte Nacht geraubt hat.
Ich lese eine XML aus und schreibe die Werte in ein DOM. Die Ergebnisse schreibe ich anschließend in eine DB.
Das funktioniert auch inzwischen sehr gut. Nun habe ich aber ein Problem mit einer Schleife.
Es werden aus der XML mehrere IDs für Elemente ausgelesen.
HTML:
     [0] => i2121
    [1] => i2166
    [2] => i2076
    [3] => i1931
    [4] => i2014
Nun soll in einer weiteren Schleife jede einzelne ID in der XML durchlaufen werden und die zugehörigen Referenzen gefunden werden.
So kann zum Beispiel die ID i1931 auf zwei weitere Ref_IDs verweisen. Diese sollen anschließend als Array in die zugehörige Zeile der ID in meiner DB geschrieben werden.
Also zum Beispiel:
IDRef_IDs
i2121["i2132","i2140"]
i1931["i1948","i1980"]
......

Mein aktueller Code Schreibt diese Werte zwar in meine DB, nur leider immer nur für eine ID.
Wie kann ich die Schleife in der Schleife dazu bringen diesen Durchlauf mehrfach zu machen?
Hier der Code:
PHP:
// Alle Wände im Informationsmodell suchen und die ID's in einen Array schreiben.

$IDXMLQuery = '//*/ifc:IfcWallStandardCase/@id';
$allWallNodes = $xpath->query($IDXMLQuery);
foreach ($allWallNodes as $WallIdNode){
    $WallId = $WallIdNode->nodeValue;
    $stmt = $db->prepare("SELECT XML_ID FROM ifcwall WHERE XML_ID=?");
        $stmt->bind_param('s', $WallId);
        $stmt->execute();
        $stmt->store_result();

        if($stmt->num_rows > 0){
            echo "IDs bereits vorhanden";}
             // Wenn abgefragte XML-IDs nicht vorhanden sind, werden sie in die DB geschrieben.  
        else{
           
            echo "ID nicht da";
// Denition der Abfragepfade basierend auf der Wall-ID.
            $GUIDXMLQuery = "//ifc:IfcWallStandardCase[@id='{$WallId}']/ifc:GlobalId";
            $NameXMLQuery = "//ifc:IfcWallStandardCase[@id='{$WallId}']/ifc:Name";
            $PsetIDXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
           
            $RelPsetXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
           
            $stmt = $db->prepare("INSERT INTO ifcwall (XML_ID, GUID, Name, Pset_ID) VALUES (?, ?, ?, ?)");
           
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
            foreach($xpath->query($NameXMLQuery) as $wallNameNode)
            //foreach($xpath->query($PsetIDXMLQuery) as $wallPsetNode)
            foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                $Ref_ID[] = $RelPsetNode->nodeValue;
                $string = json_encode($Ref_ID);
           }
                $stmt->bind_param("ssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $string);
                $stmt->execute();
            }// Ender der Inneren Schleife zum Definieren der Variablen und Schreiben der Werte in die DB.  
           
           
        }//Ende Else
    }// Ende Hauptschleife
Ich habe ebenfalls versucht, die Werte in einer separaten Schleife Durchlaufen zu lassen, hierbei werden aber die Ergebnisse alle in einen Array geschrieben:
PHP:
$IDXMLQuery2 = '//*/ifc:IfcWallStandardCase/@id';
$allWallNodes2 = $xpath->query($IDXMLQuery2);
foreach ($allWallNodes2 as $WallIdNode2){
    $WallId2 = $WallIdNode2->nodeValue;
   
    $GUIDXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId2}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
    foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
        $Ref[] = $wallGuidNode->nodeValue;
    }
 
                $string = json_encode($Ref);
   
   
}

echo '<pre>', print_r($string), '</pre>';
Ich hoffe ihr könnt mir helfen, ich will es endlich mal verstehen! :)
 

BIM-T

Mitglied
Hallo,
ich lese sie in diesem Pfad aus:
PHP:
$RelPsetXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
und lasse sie durch diese Schleife laufen :
PHP:
foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                $Ref_ID[] = $RelPsetNode->nodeValue;
                $string = json_encode($Ref_ID);
           }
Es wir in der gesamten XML über diesen Pfad nach der Wallid in bestimmten knoten gesucht und diese Knoten können mehrfach vorhanden sein.
Kann es sein, das ich diese Schleife gesondert betrachten muss um mehrere durchlaufe zu haben?
 

Yaslaw

n/a
Moderator
Du führst das innerhalb einer Schleife aus.
Was du sicher machen musst, ist $Ref_ID jedesmal wieder zurücksetzen, ansonsten hast du die Einträge der vorherigen $WallId jedesmal mit dabei,
PHP:
$Ref_ID = array();
foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
    $Ref_ID[] = $RelPsetNode->nodeValue;
    $string = json_encode($Ref_ID);
}


MOMENT....ARRGGGLLL.....
Du hast da ja noch mehr foreach-Schleifen. Währe der Code sauber formatiert würde man das sofort sehen
Dazu hast du auch noch Syntaxfehler. foerach ohne {}.
Was sollen all die foreach vor dem auslesen der Ids? Was soll der foreach ohne Code-Bereich?
PHP:
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
                foreach($xpath->query($NameXMLQuery) as $wallNameNode)        //Was soll der machen?

                foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                    $Ref_ID[] = $RelPsetNode->nodeValue;
                    $string = json_encode($Ref_ID);
                   }
                $stmt->bind_param("ssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $string);
                $stmt->execute();
            }
Da gehst du mehrmals durch und liest dein json jedes mal mit derselben $WallId ein. Waruzm ist das in der Schleife? Wenn dann davor.
PHP:
            $Ref_ID = array();
            foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                $Ref_ID[] = $RelPsetNode->nodeValue;
                $string = json_encode($Ref_ID);
            }
            $wallNameNode = $xpath->query($NameXMLQuery);
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
                $stmt->bind_param("ssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $string);
                $stmt->execute();
            }
Fazit: Mit Schleifen und Verschachtelungen (if() etc) ist ein sauberes formatieren des Codes extrem wichtig um den Überblick zu behalten und Abläufe zu verstehen.
 
Zuletzt bearbeitet:

BIM-T

Mitglied
Du führst das innerhalb einer Schleife aus.
Was du sicher machen musst, ist $Ref_ID jedesmal wieder zurücksetzen, ansonsten hast du die Einträge der vorherigen $WallId jedesmal mit dabei,
PHP:
$Ref_ID = array();
foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
    $Ref_ID[] = $RelPsetNode->nodeValue;
    $string = json_encode($Ref_ID);
}


MOMENT....ARRGGGLLL.....
Du hast da ja noch mehr foreach-Schleifen. Währe der Code sauber formatiert würde man das sofort sehen
Dazu hast du auch noch Syntaxfehler. foerach ohne {}.
Was sollen all die foreach vor dem auslesen der Ids? Was soll der foreach ohne Code-Bereich?
PHP:
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
                foreach($xpath->query($NameXMLQuery) as $wallNameNode)        //Was soll der machen?

                foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                    $Ref_ID[] = $RelPsetNode->nodeValue;
                    $string = json_encode($Ref_ID);
                   }
                $stmt->bind_param("ssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $string);
                $stmt->execute();
            }
Da gehst du mehrmals durch und liest dein json jedes mal mit derselben $WallId ein. Waruzm ist das in der Schleife? Wenn dann davor.
PHP:
            $Ref_ID = array();
            foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode){
                $Ref_ID[] = $RelPsetNode->nodeValue;
                $string = json_encode($Ref_ID);
            }
            $wallNameNode = $xpath->query($NameXMLQuery);
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
                $stmt->bind_param("ssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $string);
                $stmt->execute();
            }
Fazit: Mit Schleifen und Verschachtelungen (if() etc) ist ein sauberes formatieren des Codes extrem wichtig um den Überblick zu behalten und Abläufe zu verstehen.
Hmm, dann brauch ich wohl noch einmal Hilfe, ich möchte in der Hauptschleife auf Basis der WallID mehrere Abfragen gleichzeitig machen. Es soll also auf Basis der WallID die GUID, der Name und die Pset_Ref ausgelesen und in die DB geschrieben werden.
Wie kann ich das denn machen, ohne den Pfad noch einmal in eine Foreach für einen durchlauf zu packen
wie in dem Codeschnipssel :
foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
foreach($xpath->query($NameXMLQuery) as $wallNameNode)

Danke für Deine Hilfe, ich will es wirklich lernen! :-(
 

BIM-T

Mitglied
Hier noch einmal mein ganzer php Code, wie kann man hier mehrere Abfragen in der Foreach besser gestalten um die Werte in die DB zu schreiben:
PHP:
<?php
//phpinfo();
//------------------- Verbindung zur Datenbank herstellen -----------------------------------------


if ($db->connect_errno) {
    die('Sorry - gerade gibt es ein Problem');
}

// ------------------ XML-in DOM Einlesen!---------------------------------------------------------
// DOM-Dokument erzeugen.
$doc = new DOMDocument;
// Zeilenumbruch (Whitespaces) werden ignoriert
$doc->preserveWhiteSpace = false;
// XML Datei laden
$doc->Load('Raum_02_FMHO_SB01.xml');
// xpath für DOM aktivieren
$xpath = new DOMXPath($doc);

//-----------------------------------------------------------------------------------------------


//------------------- DOM- Auslesen--------------------------------------------------------------

    //-------------------- ALLGEMEINE INFORMATION ZUM OBJEKT (IfcWallStandardCase) -------------------------

// Alle Wände im Informationsmodell suchen und die ID's in einen Array schreiben.

$IDXMLQuery = '//*/ifc:IfcWallStandardCase/@id';
$allWallNodes = $xpath->query($IDXMLQuery);
foreach ($allWallNodes as $WallIdNode){
    $WallId = $WallIdNode->nodeValue;
    $stmt = $db->prepare("SELECT XML_ID FROM ifcwall WHERE XML_ID=?");
        $stmt->bind_param('s', $WallId);
        $stmt->execute();
        $stmt->store_result();
// Bedingung ob die ausgelesenen IDs bereits in der DB vorhanden sind.
        if($stmt->num_rows > 0){
            echo "IDs bereits vorhanden";}
             // Wenn abgefragte XML-IDs nicht vorhanden sind, werden sie in die DB geschrieben.   
        else{
            
            echo "ID nicht da";
            // Denition der Abfragepfade basierend auf der XML-Wall-ID.
            $GUIDXMLQuery = "//ifc:IfcWallStandardCase[@id='{$WallId}']/ifc:GlobalId";
            $NameXMLQuery = "//ifc:IfcWallStandardCase[@id='{$WallId}']/ifc:Name";
            $PsetIDXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
            $TagIDXMLQuery = "//ifc:IfcWallStandardCase[@id='{$WallId}']/ifc:Tag";
            $RelPsetXMLQuery = "//ifc:IfcRelDefinesByProperties/ifc:RelatedObjects/*[@ref='{$WallId}']/ancestor::ifc:IfcRelDefinesByProperties/@id";
            
            // Prepare Anweisung wo die Informationen hineingeschrieben werden sollen.
            $stmt = $db->prepare("INSERT INTO ifcwall (XML_ID, GUID, Name, Pset_ID, Tag_ID) VALUES (?, ?, ?, ?, ?)");
            
            // Schleifen durchlaufen die Pfade
            foreach($xpath->query($GUIDXMLQuery) as $wallGuidNode){
            $wallNameNode = $xpath->query($NameXMLQuery);
            //foreach($xpath->query($PsetIDXMLQuery) as $wallPsetNode)
            $Ref_ID = array();
            foreach($xpath->query($RelPsetXMLQuery) as $RelPsetNode)
            $Ref_ID[] = $RelPsetNode->nodeValue;
            $Rel_IDs_Psets = json_encode($Ref_ID);
                
            
            foreach($xpath->query($TagIDXMLQuery) as $wallTagIDNode)
              
                
                $stmt->bind_param("sssss", $WallId, $wallGuidNode->nodeValue, $wallNameNode->nodeValue, $Rel_IDs_Psets, $wallTagIDNode->nodeValue);
                $stmt->execute();
            }// Ender der Inneren Schleife zum Definieren der Variablen und Schreiben der Werte in die DB.   
          
            
            
        }//Ende Else
    }// Ende Hauptschleife


//-------------------- EIGENSCHAFTEN DER OBJEKTE (IfcWallStandardCase) / (Property Sets)-------------------------

    //--------- XML-Wall_ID zum auslesen der hinterlegten Property Sets der Klasse ------------------------------






// Bedingung ob die ausgelesenen IDs bereits in der DB vorhanden sind.   




?>
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

Neue Beiträge