2009-12-10 9 views
4

Je dois analyser un fichier XML avec un objet PHP. Pour le moment, je n'ai pas la moindre idée de comment faire cela, l'aide est appréciée.Analyser un fichier XML imbriqué avec PHP dans un objet

Le format XML est assez volumineux. Je dois analyser une partie qui ressemble à ceci:

<someNamespace:xmlDocument> 
<someNamespace:categories> 
    <category name="Patrick" anAttribute="numericValue" anotherAttribute="numericValue"> 
     <category name="Andrew" anAttribute="numericValue" anotherAttribute="numericValue"> 
      <category name="Alice" anAttribute="numericValue" anotherAttribute="numericValue"> 
       <category name="Thomas" anAttribute="numericValue" anotherAttribute="numericValue"> 
        <category name="Michael" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Matthew" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       </category> 
       <category name="Janet" anAttribute="numericValue" anotherAttribute="numericValue"> 
        <category name="Steven" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Christopher" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       </category> 
       <category name="Sue" anAttribute="numericValue" anotherAttribute="numericValue"/> 
      </category> 
      <category name="Charles" anAttribute="numericValue" anotherAttribute="numericValue"> 
       <category name="John" anAttribute="numericValue" anotherAttribute="numericValue"> 
        <category name="Charles" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Rosamund" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Stuart" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Rosamund" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       </category> 
       <category name="John" anAttribute="numericValue" anotherAttribute="numericValue"/> 
      </category> 
     </category> 
     <category name="Oliver" anAttribute="numericValue" anotherAttribute="numericValue"> 
      <category name="Jane" anAttribute="numericValue" anotherAttribute="numericValue"/> 
      <category name="Lucy" anAttribute="numericValue" anotherAttribute="numericValue"> 
       <category name="David" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       <category name="Robert" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       <category name="Hetty" anAttribute="numericValue" anotherAttribute="numericValue"> 
        <category name="Kenneth" anAttribute="numericValue" anotherAttribute="numericValue"/> 
        <category name="Jonathan" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       </category> 
       <category name="Freddy" anAttribute="numericValue" anotherAttribute="numericValue"/> 
       <category name="Virginia" anAttribute="numericValue" anotherAttribute="numericValue"/> 
      </category> 
     </category> 
    </category> 
</someNamespace:categories> 

Chaque « nom » et l'attribut « anAttribute » est unique.

Ce que je voudrais avoir plus tard est un objet catégories avec de nombreux objets de la catégorie ...

Merci!

Répondre

2

Définir une extension DOMDocument

class MyDOMDocument extends DOMDocument 
{ 
    public function toArray(DOMNode $oDomNode = null) 
    { 
     // return empty array if dom is blank 
     if (is_null($oDomNode) && !$this->hasChildNodes()) { 
      return array(); 
     } 
     $oDomNode = (is_null($oDomNode)) ? $this->documentElement : $oDomNode; 
     if (!$oDomNode->hasChildNodes()) { 
      $mResult = $oDomNode->nodeValue; 
     } else { 
      $mResult = array(); 
      foreach ($oDomNode->childNodes as $oChildNode) { 
       // how many of these child nodes do we have? 
       // this will give us a clue as to what the result structure should be 
       $oChildNodeList = $oDomNode->getElementsByTagName($oChildNode->nodeName); 
       $iChildCount = 0; 
       // there are x number of childs in this node that have the same tag name 
       // however, we are only interested in the # of siblings with the same tag name 
       foreach ($oChildNodeList as $oNode) { 
        if ($oNode->parentNode->isSameNode($oChildNode->parentNode)) { 
         $iChildCount++; 
        } 
       } 
       $mValue = $this->toArray($oChildNode); 
       $sKey = ($oChildNode->nodeName{0} == '#') ? 0 : $oChildNode->nodeName; 
       $mValue = is_array($mValue) ? $mValue[$oChildNode->nodeName] : $mValue; 
       // how many of thse child nodes do we have? 
       if ($iChildCount > 1) { // more than 1 child - make numeric array 
        $mResult[$sKey][] = $mValue; 
       } else { 
        $mResult[$sKey] = $mValue; 
       } 
      } 
      // if the child is <foo>bar</foo>, the result will be array(bar) 
      // make the result just 'bar' 
      if (count($mResult) == 1 && isset($mResult[0]) && !is_array($mResult[0])) { 
       $mResult = $mResult[0]; 
      } 
     } 
     // get our attributes if we have any 
     $arAttributes = array(); 
     if ($oDomNode->hasAttributes()) { 
      foreach ($oDomNode->attributes as $sAttrName=>$oAttrNode) { 
       // retain namespace prefixes 
       $arAttributes["@{$oAttrNode->nodeName}"] = $oAttrNode->nodeValue; 
      } 
     } 
     // check for namespace attribute - Namespaces will not show up in the attributes list 
     if ($oDomNode instanceof DOMElement && $oDomNode->getAttribute('xmlns')) { 
      $arAttributes["@xmlns"] = $oDomNode->getAttribute('xmlns'); 
     } 
     if (count($arAttributes)) { 
      if (!is_array($mResult)) { 
       $mResult = (trim($mResult)) ? array($mResult) : array(); 
      } 
      $mResult = array_merge($mResult, $arAttributes); 
     } 
     $arResult = array($oDomNode->nodeName=>$mResult); 
     return $arResult; 
    } 
} 

Utilisez comme cette

$mydom = new MyDOMDocument(); 
$mydom->load('test.xml'); 

print_r($mydom->toArray()); 
+0

Salut Peter, merci beaucoup! Cela m'a aidé à démarrer. Mais je n'ai pas encore terminé, alors je dois peut-être demander à nouveau ici. –

2

simplexml_load_file

<?php 
// The file test.xml contains an XML document with a root element 
// and at least an element /[root]/title. 

if (file_exists('test.xml')) { 
    $xml = simplexml_load_file('test.xml'); 

    print_r($xml); 
} else { 
    exit('Failed to open test.xml.'); 
} 
?> 
+1

savoir que cela renvoie des éléments SimpleXML et pas des objets simples. Les éléments simplexml se comportent différemment dans certains contextes. Consultez la documentation pour des exemples. –

+0

Je me demande si cela fonctionne vraiment car je sais que simpleXML a un gros problème avec les espaces de noms. –

+0

SimpleXML fonctionne très bien avec les espaces de noms, c'est juste qu'il ne se comporte pas toujours comme vous le pensez. –

Questions connexes