2016-08-09 109 views
2

Ich arbeite derzeit an einem OOP-basierten PHP-Projekt im MVC-Stil. Für mein Projekt muss ich XMLs erstellen/senden/empfangen/verarbeiten.PHP & XML-Erstellung: Knoten in falschem Elternteil

Jetzt habe ich ein großes Problem beim Erstellen von XML-Strukturen mit DOMDocument. Jedes Mal, wenn ich einen neuen XML-Knoten ohne Attribute oder Werte erstellen, werden alle Knoten danach ein Kind, wenn dieser Knoten!

Mit anderen Worten: Ich kann keinen leeren XML-Knoten ohne alle Knoten danach beeing ein Kind von dieser leeren Knoten schaffen !!!

Dieses Problem Bugs für jetzt, aber ich brauche wirklich die Art und Weise, die ich jetzt mit der XML-Erstellung beschäftigen. Ich konnte keine Lösungen finden, aber einige ähnliche Probleme.

Diese PHP testen meine XmlHandler-Klasse, die die XML-Request erzeugt:

test.php:

<?php 

include "Handler/XmlHandler.php"; 


$xmlHandler=new XmlHandler(); 

$xmlHandler->CreateNewXmlInstance(); 
$root = $xmlHandler->CreateRootNode('RootNode'); 
$l1 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel1", "Text1 - This node one has text"); 
$l2 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel2", "Text2 - Next node Level3 level is not gonna have text"); 
$l21 = $xmlHandler->AppendNodeWithChild($l2, "NodeLevel2_1", "Text2_1 - This node will be a child of Level2, everything fine"); 
$l3 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel3", ""); 
$l4 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel4", "Text4 - This node should be on same level like 3, 2 & 1, but instead it's a child of Level 3 (?!?!?!?!)"); 

echo "<p style='display:none;'>".$xmlHandler->SaveXml()."</p>"; 

?> 

Hier ist die XML-Handler-Klasse, die ich verwende, um die XML zu erstellen -request-Struktur (i geschrieben nur die notwendigen Teile der Klasse hier)

XmlHandler.php:

<?php 

class XmlHandler{ 


    private $xml; 

    /** 
    * 
    * Constructor 
    * 
    */ 

    function __construct() 
    { 
     $this->xml=null; 

    } 

    //[...] 

    /* 
    * Custom XML-Creator Functions 
    * 
    */ 

    public function CreateNewXmlInstance(){ 
     /*********************************************/ 
     /** XML DOM example of building XML Request **/ 
     /*********************************************/ 
     $this->xml = new DOMDocument('1.0', 'UTF-8'); 
     return $this->xml; 
    } 

    public function CreateRootNode($name){ 
     $rootElement = $this->xml->appendChild($this->xml->createElement($name)); 
     return $rootElement; 
    } 

    public function AppendNodeWithChild($node, $childName, $childText){ 
     $result = $node->appendChild($this->xml->createElement($childName)); 
     if(null != $childText && !empty($childText)){ 
      $result->appendChild($this->xml->createTextNode($childText)); 
     } 

     return $result; 
    } 

    public function SetNodeAttributes($node, $nameAndValues){ 
     if(null != $nameAndValues && sizeof($nameAndValues) > 0){ 
      foreach($nameAndValues as $name => $value){ 
       $this->SetNodeAttribute($node, $name, $value); 
      } 
     } 
    } 

    public function SetNodeAttribute($node, $name, $value){ 
     $node->setAttribute($name, $value); 
    } 

    public function SaveXml(){ 
     return $this->xml->saveXML(); 
    } 

    //[...] 

} 

?> 

Dies ist das Ergebnis:

<!-- ?xml version="1.0" encoding="UTF-8"? --> 
<rootnode> 
    <nodelevel1>Text1 - This node one has text</nodelevel1> 
    <nodelevel2>Text2 - Next node Level3 level is not gonna have text 
     <nodelevel2_1>Text2_1 - This node will be a child of Level2, everything fine</nodelevel2_1> 
    </nodelevel2> 
    <nodelevel3> 
     <nodelevel4>Text4 - This node should be on same level like 3, 2 &amp; 1, but instead it's a child of Level 3 (?!?!?!?!)</nodelevel4> 
    </nodelevel3> 
</rootnode> 

Aber in der Theorie sollte es so somethign sein:

<!-- ?xml version="1.0" encoding="UTF-8"? --> 
<rootnode> 
    <nodelevel1>Text1 - This node one has text</nodelevel1> 
    <nodelevel2>Text2 - Next node Level3 level is not gonna have text 
     <nodelevel2_1>Text2_1 - This node will be a child of Level2, everything fine</nodelevel2_1> 
    </nodelevel2> 
    <nodelevel3/> 
    <nodelevel4>Text4 - This node should be on same level like 3, 2 &amp; 1, but instead it's a child of Level 3 (?!?!?!?!)</nodelevel4> 
</rootnode> 

Wie Sie sehen können: Etwas schief gelaufen ist, wenn ich hatte Stellen Sie keinen Wert für den neu erstellten Knoten auf Level3 ein!

$l3 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel3", ""); 
$l4 = $xmlHandler->AppendNodeWithChild($root, "NodeLevel4", "Text4 - This node should be on same level like 3, 2 & 1, but instead it's a child of Level 3 (?!?!?!?!)"); 

Solange ich Attribute setze oder Werte in den neu erstellten Knoten setze, ist alles in Ordnung. Aber ich habe einige Situationen, wo auch reine leere Knoten erstellt werden müssen!

Meine Frage ist:

Was mache ich falsch hier?

Oder macht PHP etwas falsch?

Vielleicht macht mein Browser eine schlechte Vorbereitung der XML, aber die ausgehende XML-Anfrage wurde korrekt erstellt und gesendet und der Fehler liegt etwas anderes?

Wenn ja, wie kann ich die XML-Anfrage überprüfen?

Edit Nr.2:

Ich habe meine Frage/ursprünglichen Beitrag irgendwie geändert. Das obige Beispiel ist ein bisschen leichter zu verstehen. Zumindest hoffe ich es.

Antwort

0

Ok Leute, jemand hat mir bei diesem Problem geholfen. Hier ist das Gespräch:

Him: Die Tags falsch sind (da sie auf all-Klein geändert haben)

Me: Ja, es scheint die XML chaotisch wird nach Echo es aus in den Browser anstatt es zu speichern in eine Datei!

Him: Und die Ausgabe nicht einmal

Me formatiert werden soll: ich, dass ich für eine bessere Sicht hat

Him: Dies ist die Rohausgangssignal von $ xmlHandler- > saveXML() nach der Ausgabe

<?xml version="1.0" encoding="UTF-8"?> 
<RootNode> 
    <NodeLevel1>Text1 - This node one has text</NodeLevel1> 
    <NodeLevel2>Text2 - Next node Level3 level is not gonna have text<NodeLevel2_1>Text2_1 - This node will be a child of Level2, everything fine</NodeLevel2_1></NodeLevel2> 
    <NodeLevel3/> 
    <NodeLevel4>Text4 - This node should be on same level like 3, 2 &amp; 1, but instead it's a child of Level 3 (?!?!?!?!)</NodeLevel4> 
</RootNode> 

Me formatiert, sodass: A fter Drucken es in eine Datei, ich habe das gleiche Ergebnis wie Sie.

Fazit:

Jetzt habe ich schreibt die saveXml-Ausgabe in eine Datei. Das Ergebnis ist er selbe wie Ihm sagte mir.

Also war das Chaos?

ich thoght es ausreichen würde, die XML-out in den Browser drucken mit und überprüfen Sie es durch den HTML-Quellcode über FireFox Echo.

Wie Sie in meinem ersten Beitrag sehen können, habe ich echo ...

echo "<p style='display:none;'>".$xmlHandler->SaveXml()."</p>"; 

irgendwie aus dem Ergebnis meiner XML-Creation drucken (weil ich nicht wusste, wie sonst).

Daher war die XML-Erstellung vom Start weg ein voller Erfolg und der Fehler, den ich vom Antwort-Server bekomme, liegt woanders (von nun an kann ich mich nicht mehr auf deine Hilfe verlassen)!

0

Ihre Helferfunktionen in einer Klasse

class XMLHelper { 
    /* 
    * Custom XML-Creator Functions 
    * 
    */ 

    private $xml; 

    public function CreateNewXmlInstance(){ 
     /*********************************************/ 
     /** XML DOM example of building XML Request **/ 
     /*********************************************/ 
     $this->xml = new DOMDocument('1.0', 'UTF-8'); 
     return $this->xml; 
    } 

    public function CreateRootNode($name){ 
     $rootElement = $this->xml->appendChild($this->xml->createElement($name)); 
     return $rootElement; 
    } 

    public function AppendNodeWithChild($node, $childName, $childText){ 
     $result = $node->appendChild($this->xml->createElement($childName)); 
     if(null != $childText && !empty($childText)){ 
      $result->appendChild($this->xml->createTextNode($childText)); 
     } 

     return $result; 
    } 

    public function SetNodeAttributes($node, $nameAndValues){ 
     if(null != $nameAndValues && sizeof($nameAndValues) > 0){ 
      foreach($nameAndValues as $name => $value){ 
       $this->SetNodeAttribute($node, $name, $value); 
      } 
     } 
    } 

    public function SetNodeAttribute($node, $name, $value){ 
     $node->setAttribute($name, $value); 
    } 

    public function SaveXml(){ 
     return $this->xml->saveXML(); 
    } 
} 

Wrap Dinge in der Klasse Wickeln, weil Ihr Code $this Anrufe

Wrapping Dinge in der Klasse enthalten machen $this Anrufe Variablen muss das Programm zu korrigieren.

Neu und dann die Klasse und initialisiert werden, um die Knoten

$test = new XMLHelper(); 
$test->CreateNewXmlInstance(); 
$request = $test->CreateRootNode("request"); 
$node1 = $test->AppendNodeWithChild($request, "node1", null); 
$node2 = $test->AppendNodeWithChild($node1, "node2", null); 
$test->SetNodeAttributes($node2, array(
    "client" => "This is a testing value" 
)); 

echo $test->saveXml(); 

//Output: 
// <?xml version="1.0" encoding="UTF-8"?> 
// <request> 
//  <node1> 
//   <node2 client="This is a testing value"/> 
//  </node1> 
// </request> 

Bitte zu beachten, dass Code Bedarf in einer korrekten Reihenfolge ausgeführt.

  1. New der Wurzelknoten (request)
  2. Dann einen Knoten 1 bis (request) append
  3. Schließlich Knoten 2 zu Knoten anfügen 1
  4. Konfigurieren der Client-Wert des Knotens 2
  5. Print aus dem gesamten Wurzelknoten
  6. Dann haben Sie die Magie getan

Es ist nichts falsch mit PHP und nicht mit Ihrem Webbrowser.

Der Fehler stammt wahrscheinlich davon, dass Sie den Stammknoten nicht initialisiert haben und den erstellten Knoten nicht korrekt zum Stammknoten hinzugefügt haben.

Für XML-Validierung in PHP, siehe this link.

DOMDocument verfügt über eine integrierte Funktion zur Validierung.

bearbeiten 2016-08-10

Hier sind die überarbeitete Code Ihres Falles

class SpecificXmlHandler extends XmlHandler{ 

    /** 
    * Constructor 
    * 
    */ 

    private $errorCounter; 
    private $xmlUrl; 

    //Declare the root first 
    private $root; 

    function __construct() 
    { 
     parent::__construct(); 
     $this->errorCounter=0; 
     $this->xmlUrl=Configuration::XML_REQUEST_URL; 
    } 


    //[...] 

    /** 
    * Action Functions 
    */ 

    public function GetStaticData($requestName, $requestFilterNamesAndValues){ 
     $xml = $this->BuildStaticDataRequest($requestName, $requestFilterNamesAndValues); 
     echo "<p style='display:none'>" . $xml. "</p>";  //Request 
     $response = $this->ExecuteRequest($this->xmlUrl, $xml, null, false); 
     echo "<p style='display:none'>" . $response . "</p>"; //Resonse 

     //[...] 
    } 

    //[...] 

    /** 
    * Request Building Functions 
    */ 

    public function BuildStaticDataRequest($requestName, $requestFilterNamesAndValues){ 

     $this->CreateNewXmlInstance(); 
     //$root = $this->CreateRootNode('Request'); 
     //Use the root node you have created in the constructor by using $this 
     $this->root = $this->CreateRootNode('Request'); 
     //Generate Header (Source-Node) 
     $this->GenerateHeadData($this->root); 

     //[...] 

     return $this->SaveXml(); 
    } 

    public function GenerateHeadData($root){ 

     $clientID=Configuration::XML_CLIENT; 


     //Here the Node1 & Node2 creation 
     $node1 = $this->AppendNodeWithChild($root, "node1", null); 
     $node2 = $this->AppendNodeWithChild($node1, "node2", null); 

     $this->SetNodeAttributes($node2 , array(
      "Client" =>$clientID 
     )); 

     //Change it to return the whole root 
     return $root; 

    } 

[...] 


} 

Bitte Variablen in der Klasse erstellen und $this verwenden die privaten Variablen verweisen Sie erstellt haben.

+0

Hallo MiKeNeko und danke für Ihre Antwort. Mein Code ist bereits so, wie Sie ihn in Ihrer Antwort beschrieben haben. Wie gesagt, ich entwickle ** OOP **. Aber ich bekomme immer noch das Problem mit Node2 nicht in Node1. –

+0

Ich habe in meinem ursprünglichen Beitrag mehr von meinem Klassencode hinzugefügt. Ich kann nicht sagen, wo der Fehler ist. Ihre Schritte sind: 'New der Wurzelknoten (Anfrage) // Prüfe Dann einen Knoten anhängen 1 (Anfrage) // Prüfe Schließlich Knoten anhängen 2 an den Knoten 1 // PRÜFEN Konfigurieren Sie den Client-Wert den gesamten Wurzelknoten des Knotens 2 // Prüfe Print out // Prüfe Dann Sie die Magie // check' gemacht habe oder ich etwas fehle? –

+0

Ich habe ein Update auf die Antwort sehen, ob es hilft. Ich denke, du hast gerade ein '$ this' verpasst. Bitte sehen Sie meinen aktualisierten Code. – MiKeNeko