ILIAS  release_8 Revision v8.23
class.ilXmlWriter.php
Go to the documentation of this file.
1 <?php
31 {
32  private string $xmlStr;
33 
34  private string $version;
35 
36  private string $outEnc;
37 
38  private string $inEnc;
39 
40  private string $dtdDef = "";
41 
42  private string $stSheet = "";
43 
44  private string $genCmt = "Generated by ILIAS XmlWriter";
45 
46  public function __construct(
47  string $version = "1.0",
48  string $outEnc = "utf-8",
49  string $inEnc = "utf-8"
50  ) {
51  // initialize xml string
52  $this->xmlStr = "";
53 
54  // set properties
55  $this->version = $version;
56  $this->outEnc = $outEnc;
57  $this->inEnc = $inEnc;
58  }
59 
63  public function xmlSetDtdDef(string $dtdDef): void
64  {
65  $this->dtdDef = $dtdDef;
66  }
67 
71  private function xmlSetStSheet(string $stSheet): void
72  {
73  $this->stSheet = $stSheet;
74  }
75 
79  public function xmlSetGenCmt(string $genCmt): void
80  {
81  $this->genCmt = $genCmt;
82  }
83 
87  private function xmlEscapeData(string $data): string
88  {
89  $position = 0;
90  $length = strlen($data);
91  $escapedData = "";
92 
93  for (; $position < $length;) {
94  $character = substr($data, $position, 1);
95  $code = Ord($character);
96 
97  switch ($code) {
98  case 34:
99  $character = "&quot;";
100  break;
101 
102  case 38:
103  $character = "&amp;";
104  break;
105 
106  case 39:
107  $character = "&apos;";
108  break;
109 
110  case 60:
111  $character = "&lt;";
112  break;
113 
114  case 62:
115  $character = "&gt;";
116  break;
117 
118  default:
119  if ($code < 32) {
120  $character = ("&#" . $code . ";");
121  }
122  break;
123  }
124 
125  $escapedData .= $character;
126  $position++;
127  }
128  return $escapedData;
129  }
130 
134  private function xmlEncodeData(string $data): string
135  {
136  if ($this->inEnc == $this->outEnc) {
137  $encodedData = $data;
138  } else {
139  switch (strtolower($this->outEnc)) {
140  case "utf-8":
141  if (strtolower($this->inEnc) == "iso-8859-1") {
142  $encodedData = utf8_encode($data);
143  } else {
144  die(
145  "<b>Error</b>: Cannot encode iso-8859-1 data in " . $this->outEnc .
146  " in <b>" . __FILE__ . "</b> on line <b>" . __LINE__ . "</b><br />"
147  );
148  }
149  break;
150 
151  case "iso-8859-1":
152  if (strtolower($this->inEnc) == "utf-8") {
153  $encodedData = utf8_decode($data);
154  } else {
155  die(
156  "<b>Error</b>: Cannot encode utf-8 data in " . $this->outEnc .
157  " in <b>" . __FILE__ . "</b> on line <b>" . __LINE__ . "</b><br />"
158  );
159  }
160  break;
161 
162  default:
163  die(
164  "<b>Error</b>: Cannot encode " . $this->inEnc . " data in " . $this->outEnc .
165  " in <b>" . __FILE__ . "</b> on line <b>" . __LINE__ . "</b><br />"
166  );
167  }
168  }
169  return $encodedData;
170  }
171 
175  public function xmlFormatData(string $data): ?string
176  {
177  // regular expression for tags
178  $formatedXml = preg_replace_callback(
179  "|<[^>]*>[^<]*|",
180  [$this, "xmlFormatElement"],
181  $data
182  );
183 
184  return $formatedXml;
185  }
186 
190  private function xmlFormatElement(array $array): string
191  {
192  $found = trim($array[0]);
193 
194  static $indent;
195 
196  // linebreak (default)
197  $nl = "\n";
198 
199  $tab = str_repeat(" ", $indent * 2);
200 
201  // closing tag
202  if (substr($found, 0, 2) == "</") {
203  if ($indent) {
204  $indent--;
205  }
206  $tab = str_repeat(" ", $indent * 2);
207  } elseif (substr(
208  $found,
209  -2,
210  1
211  ) == "/" or // opening and closing, comment, ...
212  strpos($found, "/>") or
213  substr($found, 0, 2) == "<!") {
214  // do not change indent
215  } elseif (substr($found, 0, 2) == "<?") {
216  // do not change indent
217  // no linebreak
218  $nl = "";
219  } else { // opening tag
220  $indent++;
221  }
222 
223  // content
224  if (substr($found, -1) != ">") {
225  $found = str_replace(
226  ">",
227  ">\n" . str_repeat(" ", ($indent + 0) * 2),
228  $found
229  );
230  }
231 
232  return $nl . $tab . $found;
233  }
234 
238  public function xmlHeader(): void
239  {
240  // version and encoding
241  $this->xmlStr .= "<?xml version=\"" . $this->version . "\" encoding=\"" . $this->outEnc . "\"?>";
242 
243  // dtd definition
244  if ($this->dtdDef <> "") {
245  $this->xmlStr .= $this->dtdDef;
246  }
247 
248  // stSheet
249  if ($this->stSheet <> "") {
250  $this->xmlStr .= $this->stSheet;
251  }
252 
253  // generated comment
254  if ($this->genCmt <> "") {
255  $this->xmlComment($this->genCmt);
256  }
257  }
258 
262  public function xmlStartTag(
263  string $tag,
264  ?array $attrs = null,
265  bool $empty = false,
266  bool $encode = true,
267  bool $escape = true
268  ): void {
269  // write first part of the starttag
270  $this->xmlStr .= "<" . $tag;
271 
272  // check for existing attributes
273  if (is_array($attrs)) {
274  // write attributes
275  foreach ($attrs as $name => $value) {
276  if ($value === null) {
277  $value = '';
278  }
279 
280  // encode
281  if ($encode) {
282  $value = $this->xmlEncodeData($value);
283  }
284 
285  // escape
286  if ($escape) {
287  $value = $this->xmlEscapeData($value);
288  }
289 
290  $this->xmlStr .= " " . $name . "=\"" . $value . "\"";
291  }
292  }
293 
294  // write last part of the starttag
295  if ($empty) {
296  $this->xmlStr .= "/>";
297  } else {
298  $this->xmlStr .= ">";
299  }
300  }
301 
305  public function xmlEndTag(string $tag): void
306  {
307  $this->xmlStr .= "</" . $tag . ">";
308  }
309 
313  private function xmlComment(string $comment): void
314  {
315  $this->xmlStr .= "<!--" . $comment . "-->";
316  }
317 
321  public function xmlData(
322  string $data,
323  bool $encode = true,
324  bool $escape = true
325  ): void {
326  // encode
327  if ($encode) {
328  $data = $this->xmlEncodeData($data);
329  }
330 
331  // escape
332  if ($escape) {
333  $data = $this->xmlEscapeData($data);
334  }
335 
336  $this->xmlStr .= $data;
337  }
338 
342  public function xmlElement(
343  string $tag,
344  $attrs = null,
345  $data = null,
346  $encode = true,
347  $escape = true
348  ): void {
349  // check for existing data (element's content)
350  if (is_string($data) or
351  is_integer($data) or
352  is_float($data)) {
353  // write starttag
354  $this->xmlStartTag($tag, $attrs, false, $encode, $escape);
355 
356  // write text
357  $this->xmlData($data, $encode, $escape);
358 
359  // write endtag
360  $this->xmlEndTag($tag);
361  } else { // no data
362  // write starttag (= empty tag)
363  $this->xmlStartTag($tag, $attrs, true, $encode, $escape);
364  }
365  }
366 
370  public function xmlDumpFile(string $file, bool $format = true): void
371  {
372  // open file
373  if (!($fp = fopen($file, "w+"))) {
374  throw new RuntimeException(
375  "<b>Error</b>: Could not open \"" . $file . "\" for writing" .
376  " in <b>" . __FILE__ . "</b> on line <b>" . __LINE__ . "</b><br />"
377  );
378  }
379 
380  // set file permissions
381  chmod($file, 0770);
382 
383  // format xml data
384  if ($format) {
385  $xmlStr = $this->xmlFormatData($this->xmlStr);
386  } else {
387  $xmlStr = $this->xmlStr;
388  }
389 
390  // write xml data into the file
391  fwrite($fp, $xmlStr);
392 
393  // close file
394  fclose($fp);
395  }
396 
400  public function xmlDumpMem(bool $format = true): string
401  {
402  // format xml data
403  if ($format) {
404  $xmlStr = $this->xmlFormatData($this->xmlStr);
405  } else {
406  $xmlStr = $this->xmlStr;
407  }
408 
409  return $xmlStr;
410  }
411 
415  public function appendXML(string $a_str): void
416  {
417  $this->xmlStr .= $a_str;
418  }
419 
423  public function xmlClear(): void
424  {
425  // reset xml string
426  $this->xmlStr = "";
427  }
428 }
xmlData(string $data, bool $encode=true, bool $escape=true)
Writes data.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
xmlEscapeData(string $data)
Escapes reserved characters.
xmlComment(string $comment)
Writes a comment.
xmlSetGenCmt(string $genCmt)
Sets generated comment.
appendXML(string $a_str)
append xml string to document
xmlDumpFile(string $file, bool $format=true)
Dumps xml document from memory into a file.
xmlEndTag(string $tag)
Writes an endtag.
if($format !==null) $name
Definition: metadata.php:247
xmlEncodeData(string $data)
Encodes text from input encoding into output encoding.
xmlSetDtdDef(string $dtdDef)
Sets dtd definition.
xmlFormatData(string $data)
Indents text for better reading.
$format
Definition: metadata.php:235
xmlHeader()
Writes xml header.
xmlFormatElement(array $array)
Callback function for xmlFormatData; do not invoke directly.
$comment
Definition: buildRTE.php:72
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
__construct(string $version="1.0", string $outEnc="utf-8", string $inEnc="utf-8")
xmlClear()
clears xmlStr
xmlDumpMem(bool $format=true)
Returns xml document from memory.
xmlSetStSheet(string $stSheet)
Sets stylesheet.