Skip to content

Commit c3c4637

Browse files
author
Manokaran Majushan
committed
updated Doctype
1 parent 934a35b commit c3c4637

File tree

2 files changed

+24
-87
lines changed

2 files changed

+24
-87
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build
22
composer.lock
33
docs
4-
vendor
4+
vendor
5+
.idea

src/ArrayToXml.php

+22-86
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
<?php
2-
32
namespace Spatie\ArrayToXml;
4-
53
use DOMElement;
64
use DOMDocument;
75
use DOMException;
8-
6+
use DOMImplementation;
97
class ArrayToXml
108
{
119
/**
@@ -14,21 +12,12 @@ class ArrayToXml
1412
* @var DOMDocument
1513
*/
1614
protected $document;
17-
1815
/**
1916
* Set to enable replacing space with underscore.
2017
*
2118
* @var bool
2219
*/
2320
protected $replaceSpacesByUnderScoresInKeyNames = true;
24-
25-
/**
26-
* Prefix for the tags with numeric names.
27-
*
28-
* @var string
29-
*/
30-
protected $numericTagNamePrefix = 'numeric_';
31-
3221
/**
3322
* Construct a new instance.
3423
*
@@ -37,48 +26,44 @@ class ArrayToXml
3726
* @param bool $replaceSpacesByUnderScoresInKeyNames
3827
* @param string $xmlEncoding
3928
* @param string $xmlVersion
29+
* @param array $docTypeArray
4030
*
4131
* @throws DOMException
4232
*/
43-
public function __construct(array $array, $rootElement = '', $replaceSpacesByUnderScoresInKeyNames = true, $xmlEncoding = null, $xmlVersion = '1.0')
33+
public function __construct(array $array, $rootElement = '', $replaceSpacesByUnderScoresInKeyNames = true, $xmlEncoding = null, $xmlVersion = '1.0', $docTypeArray = [])
4434
{
4535
$this->document = new DOMDocument($xmlVersion, $xmlEncoding);
4636
$this->replaceSpacesByUnderScoresInKeyNames = $replaceSpacesByUnderScoresInKeyNames;
47-
4837
if ($this->isArrayAllKeySequential($array) && ! empty($array)) {
4938
throw new DOMException('Invalid Character Error');
5039
}
51-
40+
if (! empty($docTypeArray)) {
41+
$docType = $this->createDocType($docTypeArray);
42+
$this->document->appendChild($docType);
43+
}
5244
$root = $this->createRootElement($rootElement);
53-
5445
$this->document->appendChild($root);
55-
5646
$this->convertElement($root, $array);
5747
}
5848

59-
public function setNumericTagNamePrefix(string $prefix)
60-
{
61-
$this->numericTagNamePrefix = $prefix;
62-
}
63-
6449
/**
6550
* Convert the given array to an xml string.
6651
*
6752
* @param string[] $array
68-
* @param string|array $rootElement
53+
* @param string $rootElementName
6954
* @param bool $replaceSpacesByUnderScoresInKeyNames
7055
* @param string $xmlEncoding
7156
* @param string $xmlVersion
57+
* @param array $docTypeArray
7258
*
7359
* @return string
60+
* @throws DOMException
7461
*/
75-
public static function convert(array $array, $rootElement = '', $replaceSpacesByUnderScoresInKeyNames = true, $xmlEncoding = null, $xmlVersion = '1.0')
62+
public static function convert(array $array, $rootElementName = '', $replaceSpacesByUnderScoresInKeyNames = true, $xmlEncoding = null, $xmlVersion = '1.0', $docTypeArray = [])
7663
{
77-
$converter = new static($array, $rootElement, $replaceSpacesByUnderScoresInKeyNames, $xmlEncoding, $xmlVersion);
78-
64+
$converter = new static($array, $rootElementName, $replaceSpacesByUnderScoresInKeyNames, $xmlEncoding, $xmlVersion, $docTypeArray);
7965
return $converter->toXml();
8066
}
81-
8267
/**
8368
* Return as XML.
8469
*
@@ -88,7 +73,6 @@ public function toXml()
8873
{
8974
return $this->document->saveXML();
9075
}
91-
9276
/**
9377
* Return as DOM object.
9478
*
@@ -98,7 +82,6 @@ public function toDom()
9882
{
9983
return $this->document;
10084
}
101-
10285
/**
10386
* Parse individual element.
10487
*
@@ -108,17 +91,10 @@ public function toDom()
10891
private function convertElement(DOMElement $element, $value)
10992
{
11093
$sequential = $this->isArrayAllKeySequential($value);
111-
11294
if (! is_array($value)) {
113-
$value = htmlspecialchars($value);
114-
115-
$value = $this->removeControlCharacters($value);
116-
117-
$element->nodeValue = $value;
118-
95+
$element->nodeValue = htmlspecialchars($value);
11996
return;
12097
}
121-
12298
foreach ($value as $key => $data) {
12399
if (! $sequential) {
124100
if (($key === '_attributes') || ($key === '@attributes')) {
@@ -127,12 +103,6 @@ private function convertElement(DOMElement $element, $value)
127103
$element->nodeValue = htmlspecialchars($data);
128104
} elseif ((($key === '_cdata') || ($key === '@cdata')) && is_string($data)) {
129105
$element->appendChild($this->document->createCDATASection($data));
130-
} elseif ((($key === '_mixed') || ($key === '@mixed')) && is_string($data)) {
131-
$fragment = $this->document->createDocumentFragment();
132-
$fragment->appendXML($data);
133-
$element->appendChild($fragment);
134-
} elseif ($key === '__numeric') {
135-
$this->addNumericNode($element, $data);
136106
} else {
137107
$this->addNode($element, $key, $data);
138108
}
@@ -143,20 +113,6 @@ private function convertElement(DOMElement $element, $value)
143113
}
144114
}
145115
}
146-
147-
/**
148-
* Add node with numeric keys.
149-
*
150-
* @param DOMElement $element
151-
* @param string|string[] $value
152-
*/
153-
protected function addNumericNode(DOMElement $element, $value)
154-
{
155-
foreach ($value as $key => $item) {
156-
$this->convertElement($element, [$this->numericTagNamePrefix.$key => $value]);
157-
}
158-
}
159-
160116
/**
161117
* Add node.
162118
*
@@ -169,12 +125,10 @@ protected function addNode(DOMElement $element, $key, $value)
169125
if ($this->replaceSpacesByUnderScoresInKeyNames) {
170126
$key = str_replace(' ', '_', $key);
171127
}
172-
173128
$child = $this->document->createElement($key);
174129
$element->appendChild($child);
175130
$this->convertElement($child, $value);
176131
}
177-
178132
/**
179133
* Add collection node.
180134
*
@@ -187,15 +141,12 @@ protected function addCollectionNode(DOMElement $element, $value)
187141
{
188142
if ($element->childNodes->length === 0 && $element->attributes->length === 0) {
189143
$this->convertElement($element, $value);
190-
191144
return;
192145
}
193-
194-
$child = $this->document->createElement($element->tagName);
146+
$child = new DOMElement($element->tagName);
195147
$element->parentNode->appendChild($child);
196148
$this->convertElement($child, $value);
197149
}
198-
199150
/**
200151
* Add sequential node.
201152
*
@@ -208,15 +159,12 @@ protected function addSequentialNode(DOMElement $element, $value)
208159
{
209160
if (empty($element->nodeValue)) {
210161
$element->nodeValue = htmlspecialchars($value);
211-
212162
return;
213163
}
214-
215164
$child = new DOMElement($element->tagName);
216165
$child->nodeValue = htmlspecialchars($value);
217166
$element->parentNode->appendChild($child);
218167
}
219-
220168
/**
221169
* Check if array are all sequential.
222170
*
@@ -229,18 +177,11 @@ protected function isArrayAllKeySequential($value)
229177
if (! is_array($value)) {
230178
return false;
231179
}
232-
233180
if (count($value) <= 0) {
234181
return true;
235182
}
236-
237-
if (\key($value) === '__numeric') {
238-
return false;
239-
}
240-
241183
return array_unique(array_map('is_int', array_keys($value))) === [true];
242184
}
243-
244185
/**
245186
* Add attributes.
246187
*
@@ -253,7 +194,6 @@ protected function addAttributes($element, $data)
253194
$element->setAttribute($attrKey, $attrVal);
254195
}
255196
}
256-
257197
/**
258198
* Create the root element.
259199
*
@@ -264,31 +204,27 @@ protected function createRootElement($rootElement)
264204
{
265205
if (is_string($rootElement)) {
266206
$rootElementName = $rootElement ?: 'root';
267-
268207
return $this->document->createElement($rootElementName);
269208
}
270-
271209
$rootElementName = $rootElement['rootElementName'] ?? 'root';
272-
273210
$element = $this->document->createElement($rootElementName);
274-
275211
foreach ($rootElement as $key => $value) {
276212
if ($key !== '_attributes' && $key !== '@attributes') {
277213
continue;
278214
}
279-
280215
$this->addAttributes($element, $rootElement[$key]);
281216
}
282-
283217
return $element;
284218
}
285-
286219
/**
287-
* @param $valuet
288-
* @return string
220+
* Pass in an array of elements to set the doctype of the XML.
221+
* @param $docTypeArray
222+
*
223+
* @return \DOMDocumentType
289224
*/
290-
protected function removeControlCharacters($value)
225+
protected function createDocType($docTypeArray)
291226
{
292-
return preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $value);
227+
$implementation = new DOMImplementation();
228+
return $implementation->createDocumentType($docTypeArray[0], $docTypeArray[1], $docTypeArray[2]);
293229
}
294-
}
230+
}

0 commit comments

Comments
 (0)