2016-08-09 98 views
2

我正在使用MVC風格的基於OOP的PHP項目。 對於我的項目,我需要創建/發送/接收/處理XML。PHP&XML創建:錯誤父節點中的節點

現在,我創建XML結構與DOMDocument BIG問題。 每次我創建一個沒有屬性的新XML節點,所有節點之後都將是子節點,如果此節點!

換句話說:我離不開所有節點之後beeing的這個空節點孩子創建一個空XML節點

這個問題現在讓我感到困惑,但我真的需要我現在正在處理XML創建的方式。 我找不到任何解決方案,但一些類似的問題。

這個PHP測試我XmlHandler級,它創建XML請求:

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>"; 

?> 

這裏是XML的處理程序類,我用它來創建XML -request-結構(我這裏張貼類的neccessary部分)

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(); 
    } 

    //[...] 

} 

?> 

這就是結果:

<!-- ?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> 

但在理論上,應該有somethign這樣:

<!-- ?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> 

正如你可以看到:出了錯當我有沒有爲Level3上新創建的節點設置一個值!:

$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 (?!?!?!?!)"); 

只要我設置屬性或將sin值放入新創建的節點,一切都很好。 但我有一些情況下,也必須創建純空節點!

我的問題是:

什麼我錯在這裏做什麼?

還是PHP做錯了什麼?

也許我的瀏覽器對XML做了不好的準備,但傳出的XML請求是正確構建和發送的,錯誤在於別的嗎?

如果是這樣,我該如何檢查XML請求?

編輯編號2:

我改變了我的問題/原來的帖子莫名其妙。 上面的例子更容易理解。 至少我希望如此。

回答

0

好吧,有人幫我解決了這個問題。 下面是對話:

他:的標籤是錯誤的(因爲它們已經全部更改爲小寫)

我:是的,這似乎呼應後的XML變得混亂它將放入瀏覽器而不是將其保存到到文件

他:和輸出甚至不應該被格式化

我:我這樣做,我自己一個更好的視野

他:這是$原始輸出xmlHandler- > SaveXml()使得格式化的輸出

<?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> 

我後:打印它出來文件,我得到了和你一樣的結果。

結論:

現在,我已經寫了saveXml輸出到文件中。 結果與相同Him告訴我。

那麼是一團糟?

我認爲將XML打印到瀏覽器中已經足夠了echo並通過FireFox通過HTML源代碼進行檢查。

正如你可以在我的第一篇文章看,我用回聲......

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

以某種方式打印出我的XML創造的結果(因爲我不知道怎麼回事)。

因此,XML-Creation從啓動起就獲得了全面的成功,並且從響應服務器獲得的錯誤位於其他地方(從此我再也無法依靠您的幫助了)!

0

環繞你的輔助函數的一類類

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(); 
    } 
} 

換東西,因爲你的代碼包含$this電話

包裝的東西在課堂上讓$this呼叫糾正變量程序的需求。

然後新的類,並初始化節點

$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> 

請注意,代碼需要以正確的順序執行。

  1. 新根節點(請求)
  2. 然後,節點1追加到(請求)
  3. 最後追加節點2到節點1
  4. 配置節點的客戶端值2
  5. 打印出整個根節點
  6. 然後你做了魔術

PHP與您的網絡瀏覽器沒有任何問題。

錯誤可能來自您沒有初始化根節點,也沒有將創建的節點正確添加到根節點

對於php中的XML驗證,請參見this link

DOMDocument具有用於驗證的內置函數。

編輯2016年8月10日

這裏是你的情況的修改後的代碼

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; 

    } 

[...] 


} 

請在類中創建變量和使用$this指你所創建的私有變量。

+0

您好MiKeNeko,感謝您的回覆。 我的代碼已經像你在回答中描述的那樣。 就像我說的,我正在開發** OOP **。 但我仍然遇到node2不在node1中的問題。 –

+0

我在原始文章中添加了更多我的課程代碼。我不知道錯誤在哪裏。 你的步驟是: '新根節點(請求)//檢查 然後追加的節點1到(請求)//檢查 最後追加節點2到節點1 // CHECK 配置客戶端值節點2 //格紋 打印出整個根節點//檢查 那麼你所做的魔力// CHECK' 還是我失去了一些東西? –

+0

我已經對答案進行了更新,看看它是否有幫助。 我想你只是錯過了'$ this'。 請查看我更新的代碼。 – MiKeNeko