ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.DomUtil.php
Go to the documentation of this file.
1<?php
2
20
26{
27 protected static function xmlError(int $errno, string $errstr, ?string $errfile = null, ?int $errline = null, ?array $errcontext = null, bool $ret = false)
28 {
29 static $errs = array();
30
31 $tag = 'DOMDocument::validate(): ';
32 $errs[] = str_replace($tag, '', $errstr);
33
34 if ($ret === true) {
35 return $errs;
36 }
37 }
38
39 public function docFromString(string $xml, ?string &$error_str): ?\DOMDocument
40 {
41 $doc = new \DOMDocument();
42 set_error_handler('ILIAS\COPage\Dom\DomUtil::xmlError');
43 $old = ini_set('html_errors', false);
44 $success = $doc->loadXML($xml);
45 // Restore error handling
46 ini_set('html_errors', $old);
47 restore_error_handler();
48 $error_str = "";
49 if (!$success) {
50 $error_arr = self::xmlError(0, "", "", 0, null, true);
51 foreach ($error_arr as $error) {
52 $error = str_replace("DOMDocument::loadXML():", "", $error);
53 $error_str .= $error . "<br />";
54 }
55 return null;
56 }
57 return $doc;
58 }
59
60 public function validate(\DOMDocument $doc, ?string &$error, $throw = false): void
61 {
62 $ok = $doc->validate();
63
64 if (!$ok) {
65 $error = array(array("0", "Unknown Error"));
66
67 if (function_exists("libxml_get_last_error")) {
68 $err = libxml_get_last_error();
69
70 if (is_object($err)) {
71 if ($throw) {
72 throw new \ilCOPageException($err->message);
73 }
74 $error = array(array($err->code, $err->message));
75 }
76 }
77 }
78 }
79
80 public function path(\DOMDocument $doc, string $path): \DOMNodeList
81 {
82 $xpath = new \DOMXPath($doc);
83 return $xpath->query($path);
84 }
85
86 // change node name
87 public function changeName(
88 \DOMNode $node,
89 string $name,
90 bool $keep_attributes = true
91 ): \DOMNode {
92 $newnode = $node->ownerDocument->createElement($name);
93
94 foreach ($node->childNodes as $child) {
95 $child2 = $child->cloneNode(true);
96 $newnode->appendChild($child2);
97 }
98 if ($keep_attributes) {
99 foreach ($node->attributes as $attrName => $attrNode) {
100 $newnode->setAttribute($attrName, $attrNode);
101 }
102 }
103 $node->parentNode->replaceChild($newnode, $node);
104
105 return $newnode;
106 }
107
108 // Add parent
109 public function addParent(
110 \DOMNode $node,
111 string $name
112 ): \DOMNode {
113 $newnode = $node->ownerDocument->createElement($name);
114 $par = $node->parentNode;
115 if ($next_sib = $node->nextSibling) {
116 $newnode = $par->insertBefore($newnode, $next_sib);
117 } else {
118 $newnode = $par->appendChild($newnode);
119 }
120
121 $node = $par->removeChild($node);
122 $newnode->appendChild($node);
123 return $newnode;
124 }
125
126 // Replace a node by its child
127 public function replaceByChilds(\DOMNode $node): void
128 {
129 foreach ($node->childNodes as $child) {
130 $child2 = $child->cloneNode(true);
131 $node->parentNode->insertBefore($child2, $node);
132 }
133 $node->parentNode->removeChild($node);
134 }
135
136 // delete all childs of a node by names in $node_names
137 public function deleteAllChildsByName(
138 \DOMNode $parent,
139 array $node_names
140 ): void {
141 foreach ($parent->childNodes as $child) {
142 if (in_array($child->nodeName, $node_names)) {
143 $parent->removeChild($child);
144 }
145 }
146 }
147
148 public function deleteAllChilds(
149 \DOMNode $parent
150 ): void {
151 while ($parent->hasChildNodes()) {
152 $parent->removeChild($parent->firstChild);
153 }
154 }
155
159 public function setAttributes(
160 ?\DOMNode $node,
161 array $attributes
162 ): void {
163 foreach ($attributes as $attribute => $value) {
164 $this->setAttribute($node, $attribute, $value);
165 }
166 }
167
168 public function setAttribute(
169 ?\DOMNode $node,
170 string $attribute,
171 ?string $value
172 ): void {
173 if (!is_null($node)) {
174 if (!is_null($value) && $value !== "") {
175 $node->setAttribute($attribute, $value);
176 } elseif ($node->hasAttribute($attribute)) {
177 $node->removeAttribute($attribute);
178 }
179 }
180 }
181
188 public function setFirstOptionalElement(
189 \DOMNode $parent_node,
190 string $node_name,
191 array $successors,
192 string $content,
193 array $attributes,
194 bool $remove_childs = true
195 ): void {
196 $doc = $parent_node->ownerDocument;
197 $search = $successors;
198 $search[] = $node_name;
199 $child_name = "";
200 $child = null;
201
202 $found = false;
203 foreach ($parent_node->childNodes as $child) {
204 $child_name = $child->nodeName;
205 if (in_array($child_name, $search)) {
206 $found = true;
207 break;
208 }
209 }
210 // didn't find element
211 if (!$found) {
212 $new_node = $doc->createElement($node_name);
213 $new_node = $parent_node->appendChild($new_node);
214 if ($content != "") {
215 $this->setContent($new_node, $content);
216 }
217 $this->setAttributes($new_node, $attributes);
218 } else {
219 if ($child_name == $node_name) {
220 if ($remove_childs) {
221 foreach ($child->childNodes as $child2) {
222 $child->removeChild($child2);
223 }
224 }
225 if ($content != "") {
226 $this->setContent($child, $content);
227 }
228 $this->setAttributes($child, $attributes);
229 } else {
230 $new_node = $doc->createElement($node_name);
231 $new_node = $child->parentNode->insertBefore($new_node, $child);
232 if ($content != "") {
233 $this->setContent($new_node, $content);
234 }
235 $this->setAttributes($new_node, $attributes);
236 }
237 }
238 }
239
240 public function dump(\DOMNode $node): string
241 {
242 return $node->ownerDocument->saveXML($node);
243 }
244
245 public function setContent(\DOMNode $node, string $text): void
246 {
247 // the following replace has been added to conform with PHP4.
248 // A set_content("&amp;") brought a get_content() = "&" there,
249 // whereas PHP5 gives a get_content() = "&amp;"
250 $text = str_replace("&lt;", "<", $text);
251 $text = str_replace("&gt;", ">", $text);
252 $text = str_replace("&amp;", "&", $text);
253
254 $text_node = new \DOMText();
255 $text_node->appendData($text);
256 if (is_object($node->firstChild)) {
257 $node->replaceChild($text_node, $node->firstChild);
258 } else {
259 $node->appendChild($text_node);
260 }
261 }
262
263 public function getContent(\DOMNode $node): string
264 {
265 $text_node = $node->firstChild;
266
267 if (is_object($text_node)) {
268 return $text_node->textContent;
269 } else {
270 return "";
271 }
272 }
273
279 public function addElementToList(
280 \DOMNode $parent_node,
281 string $a_node_name,
282 array $a_successors,
283 string $a_content,
284 array $a_attributes
285 ): \DOMNode {
286 $doc = $parent_node->ownerDocument;
287 $search = $a_successors;
288 $child = null;
289 $childs = $parent_node->childNodes;
290 $found = false;
291 foreach ($childs as $child) {
292 $child_name = $child->nodeName;
293 if (in_array($child_name, $search)) {
294 $found = true;
295 break;
296 }
297 }
298 // didn't successors -> append at the end
299 $new_node = $doc->createElement($a_node_name);
300 if (!$found) {
301 $new_node = $parent_node->appendChild($new_node);
302 } else {
303 $new_node = $parent_node->insertBefore($new_node, $child);
304 }
305 if ($a_content != "") {
306 $this->setContent($new_node, $a_content);
307 }
308 $this->setAttributes($new_node, $a_attributes);
309
310 return $new_node;
311 }
312}
replaceByChilds(\DOMNode $node)
addParent(\DOMNode $node, string $name)
validate(\DOMDocument $doc, ?string &$error, $throw=false)
setFirstOptionalElement(\DOMNode $parent_node, string $node_name, array $successors, string $content, array $attributes, bool $remove_childs=true)
searches for an element $node_name within the childs of $parent_node if no node is found,...
setAttribute(?\DOMNode $node, string $attribute, ?string $value)
getContent(\DOMNode $node)
deleteAllChilds(\DOMNode $parent)
docFromString(string $xml, ?string &$error_str)
changeName(\DOMNode $node, string $name, bool $keep_attributes=true)
deleteAllChildsByName(\DOMNode $parent, array $node_names)
setContent(\DOMNode $node, string $text)
static xmlError(int $errno, string $errstr, ?string $errfile=null, ?int $errline=null, ?array $errcontext=null, bool $ret=false)
setAttributes(?\DOMNode $node, array $attributes)
set attributes of a node
path(\DOMDocument $doc, string $path)
addElementToList(\DOMNode $parent_node, string $a_node_name, array $a_successors, string $a_content, array $a_attributes)
Places a new node $a_node_name directly before nodes with names of $a_successors.
ilErrorHandling $error
Definition: class.ilias.php:69
$path
Definition: ltiservices.php:30
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists('../ilias.ini.php'))