Chris@14
|
1 <?php declare(strict_types = 1);
|
Chris@14
|
2 namespace TheSeer\Tokenizer;
|
Chris@14
|
3
|
Chris@14
|
4 use DOMDocument;
|
Chris@14
|
5
|
Chris@14
|
6 class XMLSerializer {
|
Chris@14
|
7
|
Chris@14
|
8 /**
|
Chris@14
|
9 * @var \XMLWriter
|
Chris@14
|
10 */
|
Chris@14
|
11 private $writer;
|
Chris@14
|
12
|
Chris@14
|
13 /**
|
Chris@14
|
14 * @var Token
|
Chris@14
|
15 */
|
Chris@14
|
16 private $previousToken;
|
Chris@14
|
17
|
Chris@14
|
18 /**
|
Chris@14
|
19 * @var NamespaceUri
|
Chris@14
|
20 */
|
Chris@14
|
21 private $xmlns;
|
Chris@14
|
22
|
Chris@14
|
23 /**
|
Chris@14
|
24 * XMLSerializer constructor.
|
Chris@14
|
25 *
|
Chris@14
|
26 * @param NamespaceUri $xmlns
|
Chris@14
|
27 */
|
Chris@14
|
28 public function __construct(NamespaceUri $xmlns = null) {
|
Chris@14
|
29 if ($xmlns === null) {
|
Chris@14
|
30 $xmlns = new NamespaceUri('https://github.com/theseer/tokenizer');
|
Chris@14
|
31 }
|
Chris@14
|
32 $this->xmlns = $xmlns;
|
Chris@14
|
33 }
|
Chris@14
|
34
|
Chris@14
|
35 /**
|
Chris@14
|
36 * @param TokenCollection $tokens
|
Chris@14
|
37 *
|
Chris@14
|
38 * @return DOMDocument
|
Chris@14
|
39 */
|
Chris@14
|
40 public function toDom(TokenCollection $tokens): DOMDocument {
|
Chris@14
|
41 $dom = new DOMDocument();
|
Chris@14
|
42 $dom->preserveWhiteSpace = false;
|
Chris@14
|
43 $dom->loadXML($this->toXML($tokens));
|
Chris@14
|
44
|
Chris@14
|
45 return $dom;
|
Chris@14
|
46 }
|
Chris@14
|
47
|
Chris@14
|
48 /**
|
Chris@14
|
49 * @param TokenCollection $tokens
|
Chris@14
|
50 *
|
Chris@14
|
51 * @return string
|
Chris@14
|
52 */
|
Chris@14
|
53 public function toXML(TokenCollection $tokens): string {
|
Chris@14
|
54 $this->writer = new \XMLWriter();
|
Chris@14
|
55 $this->writer->openMemory();
|
Chris@14
|
56 $this->writer->setIndent(true);
|
Chris@14
|
57 $this->writer->startDocument();
|
Chris@14
|
58 $this->writer->startElement('source');
|
Chris@14
|
59 $this->writer->writeAttribute('xmlns', $this->xmlns->asString());
|
Chris@14
|
60 $this->writer->startElement('line');
|
Chris@14
|
61 $this->writer->writeAttribute('no', '1');
|
Chris@14
|
62
|
Chris@14
|
63 $this->previousToken = $tokens[0];
|
Chris@14
|
64 foreach ($tokens as $token) {
|
Chris@14
|
65 $this->addToken($token);
|
Chris@14
|
66 }
|
Chris@14
|
67
|
Chris@14
|
68 $this->writer->endElement();
|
Chris@14
|
69 $this->writer->endElement();
|
Chris@14
|
70 $this->writer->endDocument();
|
Chris@14
|
71
|
Chris@14
|
72 return $this->writer->outputMemory();
|
Chris@14
|
73 }
|
Chris@14
|
74
|
Chris@14
|
75 /**
|
Chris@14
|
76 * @param Token $token
|
Chris@14
|
77 */
|
Chris@14
|
78 private function addToken(Token $token) {
|
Chris@14
|
79 if ($this->previousToken->getLine() < $token->getLine()) {
|
Chris@14
|
80 $this->writer->endElement();
|
Chris@14
|
81
|
Chris@14
|
82 $this->writer->startElement('line');
|
Chris@14
|
83 $this->writer->writeAttribute('no', (string)$token->getLine());
|
Chris@14
|
84 $this->previousToken = $token;
|
Chris@14
|
85 }
|
Chris@14
|
86
|
Chris@14
|
87 if ($token->getValue() !== '') {
|
Chris@14
|
88 $this->writer->startElement('token');
|
Chris@14
|
89 $this->writer->writeAttribute('name', $token->getName());
|
Chris@14
|
90 $this->writer->writeRaw(htmlspecialchars($token->getValue(), ENT_NOQUOTES | ENT_DISALLOWED | ENT_XML1));
|
Chris@14
|
91 $this->writer->endElement();
|
Chris@14
|
92 }
|
Chris@14
|
93 }
|
Chris@14
|
94 }
|