2009-12-10 1 views
4

Мне нужно разобрать XML-файл с PHP на объект. На данный момент у меня нет понятия, как это сделать, помощь приветствуется.Разбор вложенного xml с PHP на объект

xml довольно большой. Я должен разобрать часть, которая выглядит следующим образом:

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

Каждый «имя» и атрибут «anAttribute» является уникальным.

То, что я хотел бы иметь впоследствии находитесь в категории объекта со многими объектами категории ...

Спасибо!

ответ

2

Определить расширение для 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; 
    } 
} 

Используйте как этот

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

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

Привет, Питер, большое спасибо! Это помогло мне начать. Но я еще не закончил, так что, может быть, мне придется снова спросить здесь. – 2009-12-11 02:09:43

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

быть в курсе, что это возвращает элементы SimpleXML, а не простые объекты. Элементы simplexml ведут себя по-разному в некоторых контекстах. Проверьте документацию на примерах. –

+0

Интересно, действительно ли это работает, поскольку я знаю, что simpleXML имеет большую проблему с пространствами имен. –

+0

SimpleXML отлично работает с пространствами имен, просто он не всегда ведет себя так, как вы думаете. –

Смежные вопросы