* @author Pavel Kulbakin
* @package General
*/
require_once dirname(__FILE__) . '/XmlImportTemplate.php';
/**
* Is used to parse XML using specified template and root node
*/
class XmlImportParser {
/**
* SimpleXmlElement instance for the xml file
*
* @var SimpleXMLElement
*/
protected $xml;
/**
* XPath expression for selecting the root node of the record
*
* @var string
*/
protected $rootNodeXPath;
/**
* Path to cached template
*
* @var string
*/
protected $cachedTemplate;
/**
* Creates new parser instance
*
* @param string $xml
* @param string $rootNodeXPath XPath for the record root node
* @param string $cachedTemplate path to cached template
* @param bool $isURL whether xml is URL or path
*/
public function __construct($xml, $rootNodeXPath, $cachedTemplate, $isURL = false)
{
if ($isURL) {
$xml = file_get_contents($xml);
}
// FIX: remove default namespace because libxml xpath implementation doesn't handle it properly
$xml and $xml = preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml);
libxml_use_internal_errors(true);
try{
$this->xml = new SimpleXMLElement($xml);
} catch (Exception $e){
try{
$this->xml = new SimpleXMLElement(utf8_encode($xml));
} catch (Exception $e){
throw new XmlImportException($e->getMessage());
}
}
$this->rootNodeXPath = $rootNodeXPath;
$this->cachedTemplate = $cachedTemplate;
}
/**
* Gets the parser results for all records or
* the part of them if $start and $count parameters are passed
*
* @param array[optional] $records Sequence numbers of records to import (first record corresponds to 1)
* @return array
*/
public function parse($records = array())
{
empty($records) or is_array($records) or $records = array($records);
$result = array();
$rootNodes = $this->xml->xpath($this->rootNodeXPath);
if ($rootNodes === false)
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
for ($i = 0; $i < count($rootNodes); $i++) {
if (empty($records) or in_array($i + 1, $records)) {
$rootNode = apply_filters('wpallimport_xml_row', $rootNodes[$i]);
$template = new XmlImportTemplate($rootNode, $this->cachedTemplate);
$result[] = $template->parse();
}
}
return $result;
}
/**
* Creates new parser instance for text template specified
*
* @param string $xml
* @param string $rootNodeXPath XPath for the record root node
* @param string $template template
* @param string &$file path to the cached template
* @return XmlImportParser
*/
public static function factory($xml, $rootNodeXPath, $template, &$file = NULL)
{
$scanner = new XmlImportTemplateScanner();
$tokens = $scanner->scan(new XmlImportStringReader($template));
$t_parser = new XmlImportTemplateParser($tokens);
$tree = $t_parser->parse();
$codegenerator = new XmlImportTemplateCodeGenerator($tree);
$file = $codegenerator->generate();
return new self($xml, $rootNodeXPath, $file);
}
}