<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */


class XmlFileReader
{
  
  private $pathToXml;
  
  private $xPath;

  
  public function __construct($pPathToXml)
  {
    $this->setPathToXml($pPathToXml);
  }

  
  public function getPathToXml()
  {
    return $this->pathToXml;
  }

  
  public function setPathToXml($pPathToXml)
  {
    $this->pathToXml = $pPathToXml;
  }

  
  public function getObjectForAllMatchingNodes($pXPathQuery)
  {
    $domNodeList = $this->doXPathQuery($pXPathQuery);

    $rootObj = new XElement();

    foreach ($domNodeList as $domNode) {
      $this->addDomNodeAsStdClassObjectOrArrayWithStdClassObjects($rootObj, $domNode->nodeName, $domNode);
    }

    return $rootObj;
  }

  
  public function getObjectForFirstMatchingNode($pXPathQuery)
  {
    $domNodeList = $this->doXPathQuery($pXPathQuery);
    $domNode = $domNodeList->item(0);
    $obj = $this->getObjectFromDomNode($domNode);
    if ($obj != null) {
      $tmp = new XElement();
      $name = $domNode->nodeName;
      $tmp->{$name} = $obj;
      $obj = $tmp;
    }

    return $obj;
  }

  
  private function getObjectFromDomNode($pDOMNode)
  {
    if ($pDOMNode == '') {
      return null;
    }

    
    $obj = new XElement();

    
    
    

    if ($pDOMNode->attributes->length > 0) {
      $attributes = new XElement();
      foreach ($pDOMNode->attributes as $attributeNode) {
        $name = $attributeNode->nodeName;
        $attributes->{$name} = $attributeNode->nodeValue;
      }
      $obj->_attributes = $attributes;
    }

    
    
    
    
    

    foreach ($pDOMNode->childNodes as $childNode) {
      $name = $childNode->nodeName;
      switch ($childNode->nodeType) {
        case XML_ELEMENT_NODE:
          
          $this->addDomNodeAsStdClassObjectOrArrayWithStdClassObjects($obj, $name, $childNode);
          break;
        case XML_TEXT_NODE:
          return $childNode->nodeValue;
        default:
          
          
          break;
      }
    }

    return $obj;
  }

  
  private function addDomNodeAsStdClassObjectOrArrayWithStdClassObjects($pObject, $pMemberName, $pDomNode)
  {
    if (isset($pObject->{$pMemberName})) {
      if (is_array($pObject->{$pMemberName})) {
        $pObject->{$pMemberName}[] = $this->getObjectFromDomNode($pDomNode);
      } else {
        
        $tmp = $pObject->{$pMemberName};
        $pObject->{$pMemberName} = array($tmp, $this->getObjectFromDomNode($pDomNode));
      }
    } else {
      
      $pObject->{$pMemberName} = $this->getObjectFromDomNode($pDomNode);
    }
  }

  
  public function getValue($pXPathQuery)
  {
    $domNode = $this->getDomNode($pXPathQuery);

    return $domNode->nodeValue;
  }

  
  public function getValueArray($pXPathQuery)
  {
    $domNodeArray = $this->getDomNodeArray($pXPathQuery);
    $ret = array();
    for ($i = 0; $i < count($domNodeArray); ++$i) {
      $ret[] = $domNodeArray[$i];
    }

    return $ret;
  }

  
  public function getDomNode($pXPathQuery)
  {
    $res = $this->doXPathQuery($pXPathQuery);

    return $res->item(0);
  }

  
  public function getDomNodeArray($pXPathQuery)
  {
    $domNodeList = $this->doXPathQuery($pXPathQuery);
    $ret = array();
    for ($i = 0; $i < $domNodeList->length; ++$i) {
      $ret[] = $domNodeList->item($i);
    }

    return $ret;
  }

  
  public function doXPathQuery($pXPathQuery)
  {
    if ($this->xPath === null) {
      $this->openDocument($this->getPathToXml());
    }

    return $this->xPath->query($pXPathQuery);
  }

  
  private function openDocument($pPathToXml)
  {
    $domDocument = new DomDocument();
    $domDocument->preserveWhiteSpace = false;
    $domDocument->Load($pPathToXml);
    $this->xPath = new DomXpath($domDocument);
  }
}