class XMLArrayInstance in Campaign Monitor 5.2
XMLArrayInstance, xml2array() and array2xml() will be used to convert data between XML and Array. We're using a class because that is the only way we can safely use xml_parse() and other related functions (the alternative is to use $GLOBALS to hold data).
XMLArrayInstance can be initialized to start processing from a specific path in the XML. In the case of Campaign Monitor, we want to start from '/soap:Envelope/soap:Body', which is the default 2nd parameter for xml2array().
@package CampaignMonitorLib @subpackage CMBase
Hierarchy
- class \XMLArrayInstance
Expanded class hierarchy of XMLArrayInstance
File
- lib/
CMBase.php, line 576
View source
class XMLArrayInstance {
var $root = '/';
var $rootStart = 0;
var $stack = array();
var $stack_path = '';
var $stack_sz = 0;
var $array = array();
var $arrCurrent = null;
var $inRoot = false;
var $counter = 0;
var $stack_count = array();
var $stack_prefix = '/';
var $data_buffer = array();
/**
* @param string $root An absolute path that points to where XML data
* should start being converted to an array. Do not add an ending '/'.
*/
function XMLArrayInstance($root = null) {
if ($root != null && $root != '/') {
$this->root = $root;
$this->rootStart = substr_count($root, '/');
$this->stack_prefix = $root . '/';
}
}
// function default( $parser, $data ) {}
// function startNS( $parser, $userdata, $prefix, $uri ) {}
function start($parser, $ele, $atts) {
$this->stack[] = $ele;
$this->stack_path = '/' . implode('/', $this->stack);
$this->stack_sz++;
if (!isset($this->stack_count[$this->stack_path])) {
$this->stack_count[$this->stack_path] = -1;
}
$this->stack_count[$this->stack_path]++;
$this->data_buffer[$this->stack_path] = '';
}
function data($parser, $data) {
$data = trim($data);
// if $data is empty or we're not within start path, skip
if (strpos($this->stack_path, $this->root) !== 0 || $data == '') {
return;
}
// delay inserting the data, because the parser handles entities as a
// separate call. that meant that before buffering data, a simple text node
// would be broken up into multiple parts because of the entities.
$this->data_buffer[$this->stack_path] .= $data;
}
// function ddefault( $parser, $data ) { }
function end($parser, $ele) {
if ($this->data_buffer[$this->stack_path] != '') {
$this
->setArrValue($this->data_buffer[$this->stack_path]);
}
array_pop($this->stack);
$this->stack_path = '/' . implode('/', $this->stack);
$this->stack_sz--;
}
function setArrValue($data) {
// iterate through $arr to find the right element and populate it.
// if the element doesn't exist, set it as a scalar. otherwise,
// convert it to an array first and then append the value.
$ptr =& $this->array;
// the depth to insert the value at
$depth = $this->stack_sz - 1;
$sep = '';
$partial = '';
for ($i = $this->rootStart; $i < $this->stack_sz; $i++) {
$key = $this->stack[$i];
$partial .= $sep . $key;
$sep = '/';
$_c = $this->stack_count[$this->stack_prefix . $partial];
//echo "$key : [{$this->stack_prefix}]$partial\n";
// this current path doesn't exist. either we're going deeper
// into the XML (and the paths haven't been created yet), or the
// node we're on hasn't been created.
if (!isset($ptr[$key])) {
if ($i == $depth) {
$ptr[$key] = $data;
}
else {
$ptr[$key] = array();
}
$ptr =& $ptr[$key];
}
elseif ($i < $depth) {
// if the absolute path of this node has more than one occurrence, $_c > 0.
// if that's the case, then, we need to test if the node is currently a hash
// or a list. if it's a hash, convert it to a list. then, check that the list
// item exists (create it if it doesn't).
// if it's just a single occurrence, set the pointer to the hash.
if ($_c > 0) {
if (!isset($ptr[$key][0])) {
$tmp = $ptr[$key];
$ptr[$key] = array(
$tmp,
);
}
if (!isset($ptr[$key][$_c])) {
$ptr[$key][$_c] = array();
}
$ptr =& $ptr[$key][$_c];
}
else {
$ptr =& $ptr[$key];
}
}
elseif ($i == $depth) {
// the current node exists. but, since it's not an array, we need
// to convert it first.
if (!is_array($ptr[$key])) {
$tmp = $ptr[$key];
$ptr[$key] = array(
$tmp,
);
}
elseif (!isset($ptr[$key][0])) {
$tmp = $ptr[$key];
$ptr[$key] = array(
$tmp,
);
}
$ptr[$key][] = $data;
$ptr =& $ptr[$key];
}
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
property | |||
XMLArrayInstance:: |
function | |||
XMLArrayInstance:: |
function | |||
XMLArrayInstance:: |
function | |||
XMLArrayInstance:: |
function | |||
XMLArrayInstance:: |
function | * |