1
|
|
|
<?php
|
2
|
|
|
/**
|
3
|
|
|
* @author Niels A.D.
|
4
|
|
|
* @author Todd Burry <[email protected]>
|
5
|
|
|
* @copyright 2010 Niels A.D., 2014 Todd Burry
|
6
|
|
|
* @license http://opensource.org/licenses/LGPL-2.1 LGPL-2.1
|
7
|
|
|
* @package pQuery
|
8
|
|
|
*/
|
9
|
|
|
|
10
|
|
|
namespace pQuery;
|
11
|
|
|
|
12
|
|
|
/**
|
13
|
|
|
* Converts a XML document to an array
|
14
|
|
|
*/
|
15
|
|
|
class XML2ArrayParser extends HtmlParserBase {
|
16
|
|
|
|
17
|
|
|
/**
|
18
|
|
|
* Holds the document structure
|
19
|
|
|
* @var array array('name' => 'tag', 'attrs' => array('attr' => 'val'), 'childen' => array())
|
20
|
|
|
*/
|
21
|
|
|
var $root = array(
|
22
|
|
|
'name' => '',
|
23
|
|
|
'attrs' => array(),
|
24
|
|
|
'children' => array()
|
25
|
|
|
);
|
26
|
|
|
|
27
|
|
|
/**
|
28
|
|
|
* Current parsing hierarchy
|
29
|
|
|
* @var array
|
30
|
|
|
* @access private
|
31
|
|
|
*/
|
32
|
|
|
var $hierarchy = array();
|
33
|
|
|
|
34
|
|
|
protected function parse_hierarchy($self_close) {
|
35
|
|
|
if ($this->status['closing_tag']) {
|
36
|
|
|
$found = false;
|
37
|
|
|
for ($count = count($this->hierarchy), $i = $count - 1; $i >= 0; $i--) {
|
38
|
|
|
if (strcasecmp($this->hierarchy[$i]['name'], $this->status['tag_name']) === 0) {
|
39
|
|
|
|
40
|
|
|
for($ii = ($count - $i - 1); $ii >= 0; $ii--) {
|
41
|
|
|
$e = array_pop($this->hierarchy);
|
42
|
|
|
if ($ii > 0) {
|
43
|
|
|
$this->addError('Closing tag "'.$this->status['tag_name'].'" while "'.$e['name'].'" is not closed yet');
|
44
|
|
|
}
|
45
|
|
|
}
|
46
|
|
|
|
47
|
|
|
$found = true;
|
48
|
|
|
break;
|
49
|
|
|
}
|
50
|
|
|
}
|
51
|
|
|
|
52
|
|
|
if (!$found) {
|
53
|
|
|
$this->addError('Closing tag "'.$this->status['tag_name'].'" which is not open');
|
54
|
|
|
}
|
55
|
|
|
} else {
|
56
|
|
|
$tag = array(
|
57
|
|
|
'name' => $this->status['tag_name'],
|
58
|
|
|
'attrs' => $this->status['attributes'],
|
59
|
|
|
'children' => array()
|
60
|
|
|
);
|
61
|
|
|
if ($this->hierarchy) {
|
|
|
|
|
62
|
|
|
$current =& $this->hierarchy[count($this->hierarchy) - 1];
|
63
|
|
|
$current['children'][] = $tag;
|
64
|
|
|
$tag =& $current['children'][count($current['children']) - 1];
|
65
|
|
|
unset($current['tagData']);
|
66
|
|
|
} else {
|
67
|
|
|
$this->root = $tag;
|
68
|
|
|
$tag =& $this->root;
|
69
|
|
|
$self_close = false;
|
70
|
|
|
}
|
71
|
|
|
if (!$self_close) {
|
72
|
|
|
$this->hierarchy[] =& $tag;
|
73
|
|
|
}
|
74
|
|
|
}
|
75
|
|
|
}
|
76
|
|
|
|
77
|
|
|
function parse_tag_default() {
|
|
|
|
|
78
|
|
|
if (!parent::parse_tag_default()) {return false;}
|
79
|
|
|
|
80
|
|
|
if ($this->status['tag_name'][0] !== '?') {
|
81
|
|
|
$this->parse_hierarchy(($this->status['self_close']) ? true : null);
|
82
|
|
|
}
|
83
|
|
|
return true;
|
84
|
|
|
}
|
85
|
|
|
|
86
|
|
|
function parse_text() {
|
|
|
|
|
87
|
|
|
parent::parse_text();
|
88
|
|
|
if (($this->status['text'] !== '') && $this->hierarchy) {
|
|
|
|
|
89
|
|
|
$current =& $this->hierarchy[count($this->hierarchy) - 1];
|
90
|
|
|
if (!$current['children']) {
|
91
|
|
|
$current['tagData'] = $this->status['text'];
|
92
|
|
|
}
|
93
|
|
|
}
|
94
|
|
|
}
|
95
|
|
|
|
96
|
|
|
function parse_all() {
|
|
|
|
|
97
|
|
|
return ((parent::parse_all()) ? $this->root : false);
|
98
|
|
|
}
|
99
|
|
|
}
|
100
|
|
|
|
101
|
|
|
?> |
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.