Completed
Branch master (099915)
by Fabio
08:02
created

TXmlElement::toString()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 22
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 22
ccs 17
cts 17
cp 1
crap 6
rs 9.0777
1
<?php
2
/**
3
 * TXmlElement, TXmlDocument, TXmlElementList class file
4
 *
5
 * @author Qiang Xue <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 * @package Prado\Xml
9
 */
10
11
namespace Prado\Xml;
12
13
use \Prado\TPropertyValue;
14
use \Prado\Collections\TList;
15
use \Prado\Collections\TMap;
16
17
/**
18
 * TXmlElement class.
19
 *
20
 * TXmlElement represents an XML element node.
21
 * You can obtain its tag-name, attributes, text between the opening and closing
22
 * tags via the TagName, Attributes, and Value properties, respectively.
23
 * You can also retrieve its parent and child elements by Parent and Elements
24
 * properties, respectively.
25
 *
26
 * TBD: xpath
27
 *
28
 * @author Qiang Xue <[email protected]>
29
 * @package Prado\Xml
30
 * @since 3.0
31
 */
32
class TXmlElement extends \Prado\TComponent
33
{
34
	/**
35
	 * @var TXmlElement parent of this element
36
	 */
37
	private $_parent;
38
	/**
39
	 * @var string tag-name of this element
40
	 */
41
	private $_tagName = 'unknown';
42
	/**
43
	 * @var string text enclosed between opening and closing tags of this element
44
	 */
45
	private $_value = '';
46
	/**
47
	 * @var TXmlElementList list of child elements of this element
48
	 */
49
	private $_elements;
50
	/**
51
	 * @var TMap attributes of this element
52
	 */
53
	private $_attributes;
54
55
	/**
56
	 * Constructor.
57
	 * @param string $tagName tag-name for this element
58
	 */
59 25
	public function __construct($tagName)
60
	{
61 25
		$this->setTagName($tagName);
62 25
	}
63
64
	/**
65
	 * @return TXmlElement parent element of this element
66
	 */
67 15
	public function getParent()
68
	{
69 15
		return $this->_parent;
70
	}
71
72
	/**
73
	 * @param TXmlElement $parent parent element of this element
74
	 */
75 15
	public function setParent($parent)
76
	{
77 15
		$this->_parent = $parent;
78 15
	}
79
80
	/**
81
	 * @return string tag-name of this element
82
	 */
83 3
	public function getTagName()
84
	{
85 3
		return $this->_tagName;
86
	}
87
88
	/**
89
	 * @param string $tagName tag-name of this element
90
	 */
91 25
	public function setTagName($tagName)
92
	{
93 25
		$this->_tagName = $tagName;
94 25
	}
95
96
	/**
97
	 * @return string text enclosed between opening and closing tag of this element
98
	 */
99 7
	public function getValue()
100
	{
101 7
		return $this->_value;
102
	}
103
104
	/**
105
	 * @param string $value text enclosed between opening and closing tag of this element
106
	 */
107 9
	public function setValue($value)
108
	{
109 9
		$this->_value = TPropertyValue::ensureString($value);
110 9
	}
111
112
	/**
113
	 * @return bool true if this element has child elements
114
	 */
115 6
	public function getHasElement()
116
	{
117 6
		return $this->_elements !== null && $this->_elements->getCount() > 0;
118
	}
119
120
	/**
121
	 * @return bool true if this element has attributes
122
	 */
123 1
	public function getHasAttribute()
124
	{
125 1
		return $this->_attributes !== null && $this->_attributes->getCount() > 0;
126
	}
127
128
	/**
129
	 * @param string $name attribute name
130
	 * @return string the attribute specified by the name, null if no such attribute
131
	 */
132 10
	public function getAttribute($name)
133
	{
134 10
		if ($this->_attributes !== null) {
135 10
			return $this->_attributes->itemAt($name);
136
		} else {
137 1
			return null;
138
		}
139
	}
140
141
	/**
142
	 * @param string $name attribute name
143
	 * @param string $value attribute value
144
	 */
145 4
	public function setAttribute($name, $value)
146
	{
147 4
		$this->getAttributes()->add($name, TPropertyValue::ensureString($value));
148 4
	}
149
150
	/**
151
	 * @return TXmlElementList list of child elements
152
	 */
153 12
	public function getElements()
154
	{
155 12
		if (!$this->_elements) {
156 12
			$this->_elements = new TXmlElementList($this);
157
		}
158 12
		return $this->_elements;
159
	}
160
161
	/**
162
	 * @return TMap list of attributes
163
	 */
164 12
	public function getAttributes()
165
	{
166 12
		if (!$this->_attributes) {
167 12
			$this->_attributes = new TMap;
168
		}
169 12
		return $this->_attributes;
170
	}
171
172
	/**
173
	 * @param mixed $tagName
174
	 * @return TXmlElement the first child element that has the specified tag-name, null if not found
175
	 */
176 1
	public function getElementByTagName($tagName)
177
	{
178 1
		if ($this->_elements) {
179 1
			foreach ($this->_elements as $element) {
180 1
				if ($element->_tagName === $tagName) {
181 1
					return $element;
182
				}
183
			}
184
		}
185 1
		return null;
186
	}
187
188
	/**
189
	 * @param mixed $tagName
190
	 * @return TList list of all child elements that have the specified tag-name
191
	 */
192 11
	public function getElementsByTagName($tagName)
193
	{
194 11
		$list = new TList;
195 11
		if ($this->_elements) {
196 11
			foreach ($this->_elements as $element) {
197 11
				if ($element->_tagName === $tagName) {
198 11
					$list->add($element);
199
				}
200
			}
201
		}
202 11
		return $list;
203
	}
204
205
	/**
206
	 * @param mixed $indent
207
	 * @return string string representation of this element
208
	 */
209 5
	public function toString($indent = 0)
210
	{
211 5
		$attr = '';
212 5
		if ($this->_attributes !== null) {
213 5
			foreach ($this->_attributes as $name => $value) {
214 5
				$value = $this->xmlEncode($value);
215 5
				$attr .= " $name=\"$value\"";
216
			}
217
		}
218 5
		$prefix = str_repeat(' ', $indent * 4);
219 5
		if ($this->getHasElement()) {
220 4
			$str = $prefix . "<{$this->_tagName}$attr>\n";
221 4
			foreach ($this->getElements() as $element) {
222 4
				$str .= $element->toString($indent + 1) . "\n";
223
			}
224 4
			$str .= $prefix . "</{$this->_tagName}>";
225 4
			return $str;
226 5
		} elseif (($value = $this->getValue()) !== '') {
227 1
			$value = $this->xmlEncode($value);
228 1
			return $prefix . "<{$this->_tagName}$attr>$value</{$this->_tagName}>";
229
		} else {
230 5
			return $prefix . "<{$this->_tagName}$attr />";
231
		}
232
	}
233
234
	/**
235
	 * Magic-method override. Called whenever this element is used as a string.
236
	 * <code>
237
	 * $element = new TXmlElement('tag');
238
	 * echo $element;
239
	 * </code>
240
	 * or
241
	 * <code>
242
	 * $element = new TXmlElement('tag');
243
	 * $xml = (string)$element;
244
	 * </code>
245
	 * @return string string representation of this element
246
	 */
247 1
	public function __toString()
248
	{
249 1
		return $this->toString();
250
	}
251
252 5
	private function xmlEncode($str)
253
	{
254 5
		return strtr($str, [
255 5
			'>' => '&gt;',
256
			'<' => '&lt;',
257
			'&' => '&amp;',
258
			'"' => '&quot;',
259
			"\r" => '&#xD;',
260
			"\t" => '&#x9;',
261
			"\n" => '&#xA;']);
262
	}
263
}
264