2016-04-26 6 views
0

Ich retreiving XML von einem api und PHP es in eine schöne geordnete Anordnung fallen mit ..Nicht Kinder von XML in PHP Rückkehr

Im Grunde ist es für eine Kategorie-Menü, 3 Ebenen der Kategorien Rückkehr, die gehen in eine 3-stufige Aufzählung.

Die erste Ebene hatte einen Knotennamen von 'CustomCategory', in diesem gibt es einen Kindknoten namens 'ChildCategory'. Dies ist perfekt, ich kann innerhalb der ersten Schleife und Echo der zweiten Ebene.

Das Problem ist, dass der Knoten der dritten Ebene in der zweiten Ebene auch 'ChildCategory' genannt wird.

Es sieht ein bisschen wie folgt:

<CustomCategories> 
    <CustomCategory> 
      <Name>Category 1</Name> 
      <ChildCategory> 
       <Name>Child 1</Name> 
       <ChildCategory> 
        <Name>Child 1a</Name> 
       </ChildCategory> 
      <ChildCategory> 
      <Name>Child 2</Name> 
      </ChildCategory> 
    </CustomCategory> 
    <CustomCategory> 
      <Name>Category 2</Name> 
    </CustomCategory> 
</CustomCategories> 

Das bedeutet, dass, wenn ich durch die erste Ebene bin Looping um die Kinder zu bekommen, ist es nicht nur auf der zweiten Ebene suchen, es durch jedes der gehen dritte Ebene der Reihe nach, da es der gleiche Knotenname ist ...

Wie kann ich meine zweite Schleife laufen lassen, aber die Kinder ignorieren?

Dies ist mein Code im Moment:

$responseDoc = new DomDocument(); 
$responseDoc->loadXML($responseXml); 

$categories=[]; 

// loop level 1 
foreach ($responseDoc->getElementsByTagName('CustomCategory') as $cat1) { 

      $Name1 = $cat1->getElementsByTagName('Name')->item(0)->nodeValue; 
      $cats1['name1'] = $Name1; 

      // loop level 2 
      foreach ($cat1->getElementsByTagName('ChildCategory') as $cat2) { 

       $Name2 = $cat2->getElementsByTagName('Name')->item(0)->nodeValue; 
       $cats2['name2'] = $Name2; 
       $cats1['subcat']= $cats2; 

      } 

      $categories[] = $cats1; 

} 

. NB: Es ist ein wenig abgespeckte als ich einige funky stuff, wie die Arrays tun bestellt erhalten, wie sie in gehen

bei In dem Moment, in dem ich dies auschecke, erstellt es eine Liste mit allen 2nd/3rd Level zusammen in einem.

Ich möchte löschte die Daten am Ende wie folgt aus:

Die Werte, die ich im Namen bekommen müssen, also kann ich sie in ein Array setzen und Echo aus wie:

<ul> 
    <li>Category 1 
     <ul> 
      <li>Child1 
       <ul> 
        <li>Child 1a</li> 
       </ul> 
      </li> 
      <li>Child 2</li> 
     </ul> 
    </li> 
    <li>Category 1</li> 
</ul> 

Jedoch kommen die Kinder der 3. Reihe in der zweiten Schleife heraus.

Vielen Dank!

+1

Geben Sie eine weitere Haupt '' Knoten innerhalb '' & erwähnen, welche Werte Sie benötigen. Das angegebene XML ist nicht gültig. –

+0

Es sieht gut aus für mich (obwohl ich eine schlaffe auf der vorletzten Zeile ... Ich werde das jetzt hinzufügen. Warum brauchen Sie eine dritte? Ich kann das hinzufügen, obwohl ..? die Werte, die ich suche Ich werde zur Frage hinzufügen .... – zombiecode

Antwort

0

DOMNode::getElementsByTagName() gibt alle untergeordneten Elementknoten mit diesem Namen zurück. Sie könnten die Eigenschaft $childNodes iterieren und jeden Knotentyp und -namen überprüfen oder Xpath verwenden.

$document = new DOMDocument(); 
$document->loadXml($xml); 
$xpath = new DOMXpath($document); 

foreach ($xpath->evaluate('/CustomCategories/CustomCategory') as $customCategory) { 
    echo $xpath->evaluate('string(Name)', $customCategory), "\n"; 
    foreach ($xpath->evaluate('ChildCategory', $customCategory) as $childCategory) { 
    echo ' -> ', $xpath->evaluate('string(Name)', $childCategory), "\n"; 
    } 
} 

Ausgang:

Category 1 
-> Child 1 
-> Child 2 
Category 2 

Sie erwähnen, dass Sie die Kategorien bestellen müssen. Eine einfache Möglichkeit besteht darin, die Knotenliste in ein Array zu konvertieren und eine benutzerdefinierte Sortierung zu verwenden.

$document = new DOMDocument(); 
$document->loadXml($xml); 
$xpath = new DOMXpath($document); 

$customCategories = iterator_to_array(
    $xpath->evaluate('/CustomCategories/CustomCategory') 
); 
// sort the categories by name, descending 
uasort(
    $customCategories, 
    function($one, $two) use ($xpath) { 
    return -1 * strcasecmp(
     $xpath->evaluate('string(Name)', $one), 
     $xpath->evaluate('string(Name)', $two) 
    ); 
    } 
); 

foreach ($customCategories as $customCategory) { 
    echo $xpath->evaluate('string(Name)', $customCategory), "\n"; 
    foreach ($xpath->evaluate('ChildCategory', $customCategory) as $childCategory) { 
    echo ' -> ', $xpath->evaluate('string(Name)', $childCategory), "\n"; 
    } 
} 

Ausgang:

Category 2 
Category 1 
-> Child 1 
-> Child 2