From eca67375281a8f7f0bf2cd786d4622d2941a3644 Mon Sep 17 00:00:00 2001 From: Roel Date: Sat, 21 Apr 2018 03:19:39 +0200 Subject: [PATCH 1/4] Extract regex patterns to its own class --- src/PhpArrayToXml.php | 51 ++++------------------------------------- src/lib/XmlPatterns.php | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 47 deletions(-) create mode 100644 src/lib/XmlPatterns.php diff --git a/src/PhpArrayToXml.php b/src/PhpArrayToXml.php index af4a1e7..03c33d1 100644 --- a/src/PhpArrayToXml.php +++ b/src/PhpArrayToXml.php @@ -4,6 +4,7 @@ use DOMDocument; use DOMElement; +use RefactorStudio\PhpArrayToXml\Lib\XmlPatterns; class PhpArrayToXml { @@ -340,7 +341,7 @@ public function getCastNullValue() */ public static function hasValidXmlTagStartingChar($value = null) { - if (preg_match(self::getValidXmlTagStartPattern(), $value) === 1) { + if (preg_match(XmlPatterns::getValidXmlTagStartPattern(), $value) === 1) { return true; } return false; @@ -354,7 +355,7 @@ public static function hasValidXmlTagStartingChar($value = null) */ public static function isValidXmlTagChar($value = null) { - if (preg_match(self::getValidXmlTagNameChar(), $value) === 1) { + if (preg_match(XmlPatterns::getValidXmlTagNameChar(), $value) === 1) { return true; } return false; @@ -372,7 +373,7 @@ public static function isValidXmlTag($value = null) return false; } - if (preg_match(self::getValidXmlTagNamePattern(), $value) === 1) { + if (preg_match(XmlPatterns::getValidXmlTagNamePattern(), $value) === 1) { return true; } return false; @@ -398,50 +399,6 @@ public function toXmlString($array = []) return $this->_doc->saveXML(); } - /** - * Get a regex pattern for valid tag names - * - * @return string - */ - protected static function getValidXmlTagNamePattern() - { - return '~ - # XML 1.0 Name symbol PHP PCRE regex - (?(DEFINE) - (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) - (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) - (? (?&NameStartChar) (?&NameChar)*) - ) - ^(?&Name)$ - ~ux'; - } - - /** - * Get a regex pattern for valid tag chars - * - * @return string - */ - protected static function getValidXmlTagNameChar() - { - return '~ - (?(DEFINE) - (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) - (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) - ) - ^(?&NameChar)$ - ~ux'; - } - - /** - * Get a regex pattern for valid tag starting characters - * - * @return string - */ - protected static function getValidXmlTagStartPattern() - { - return '~^([:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}])~ux'; - } - /** * Converts arrays to DOMDocument elements * diff --git a/src/lib/XmlPatterns.php b/src/lib/XmlPatterns.php new file mode 100644 index 0000000..86a4d1b --- /dev/null +++ b/src/lib/XmlPatterns.php @@ -0,0 +1,50 @@ + + (?(DEFINE) + (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) + (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) + (? (?&NameStartChar) (?&NameChar)*) + ) + ^(?&Name)$ + ~ux'; + } + + /** + * Get a regex pattern for valid tag chars + * + * @return string + */ + public static function getValidXmlTagNameChar() + { + return '~ + (?(DEFINE) + (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) + (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) + ) + ^(?&NameChar)$ + ~ux'; + } + + /** + * Get a regex pattern for valid tag starting characters + * + * @return string + */ + public static function getValidXmlTagStartPattern() + { + return '~^([:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}])~ux'; + } +} \ No newline at end of file From b535b322b5d2e78bab1c66524b0a609ad66c0b90 Mon Sep 17 00:00:00 2001 From: Roel Date: Sat, 21 Apr 2018 03:25:55 +0200 Subject: [PATCH 2/4] temp --- src/lib/XmlPatterns.php | 50 ----------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 src/lib/XmlPatterns.php diff --git a/src/lib/XmlPatterns.php b/src/lib/XmlPatterns.php deleted file mode 100644 index 86a4d1b..0000000 --- a/src/lib/XmlPatterns.php +++ /dev/null @@ -1,50 +0,0 @@ - - (?(DEFINE) - (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) - (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) - (? (?&NameStartChar) (?&NameChar)*) - ) - ^(?&Name)$ - ~ux'; - } - - /** - * Get a regex pattern for valid tag chars - * - * @return string - */ - public static function getValidXmlTagNameChar() - { - return '~ - (?(DEFINE) - (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) - (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) - ) - ^(?&NameChar)$ - ~ux'; - } - - /** - * Get a regex pattern for valid tag starting characters - * - * @return string - */ - public static function getValidXmlTagStartPattern() - { - return '~^([:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}])~ux'; - } -} \ No newline at end of file From fb0042403dc4e752a4c33095dcaafdb8171ace8a Mon Sep 17 00:00:00 2001 From: Roel Date: Sat, 21 Apr 2018 03:27:07 +0200 Subject: [PATCH 3/4] Add file again ( src/Lib/ ) --- src/Lib/XmlPatterns.php | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/Lib/XmlPatterns.php diff --git a/src/Lib/XmlPatterns.php b/src/Lib/XmlPatterns.php new file mode 100644 index 0000000..86a4d1b --- /dev/null +++ b/src/Lib/XmlPatterns.php @@ -0,0 +1,50 @@ + + (?(DEFINE) + (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) + (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) + (? (?&NameStartChar) (?&NameChar)*) + ) + ^(?&Name)$ + ~ux'; + } + + /** + * Get a regex pattern for valid tag chars + * + * @return string + */ + public static function getValidXmlTagNameChar() + { + return '~ + (?(DEFINE) + (? [:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}]) + (? (?&NameStartChar) | [.\\-0-9\\xB7\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]) + ) + ^(?&NameChar)$ + ~ux'; + } + + /** + * Get a regex pattern for valid tag starting characters + * + * @return string + */ + public static function getValidXmlTagStartPattern() + { + return '~^([:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}])~ux'; + } +} \ No newline at end of file From aced8a6019c050ab5c6db03d544b1fd4cf247ec8 Mon Sep 17 00:00:00 2001 From: Roel Date: Sat, 21 Apr 2018 14:36:17 +0200 Subject: [PATCH 4/4] Extract DomDocumentBuilder to its own class --- src/PhpArrayToXml.php | 255 +--------------------------- src/Traits/DomDocumentBuilder.php | 267 ++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+), 251 deletions(-) create mode 100644 src/Traits/DomDocumentBuilder.php diff --git a/src/PhpArrayToXml.php b/src/PhpArrayToXml.php index 03c33d1..a56776d 100644 --- a/src/PhpArrayToXml.php +++ b/src/PhpArrayToXml.php @@ -2,12 +2,13 @@ namespace RefactorStudio\PhpArrayToXml; -use DOMDocument; -use DOMElement; use RefactorStudio\PhpArrayToXml\Lib\XmlPatterns; +use RefactorStudio\PhpArrayToXml\Traits\DomDocumentBuilder; class PhpArrayToXml { + use DomDocumentBuilder; + const LOWERCASE = 'lowercase'; const UPPERCASE = 'uppercase'; @@ -387,256 +388,8 @@ public static function isValidXmlTag($value = null) */ public function toXmlString($array = []) { - $this->_doc = new DOMDocument($this->getVersion(), $this->getEncoding()); - $this->_doc->formatOutput = $this->getFormatOutput(); - - $root = $this->_doc->createElement($this->createValidRootName($this->getCustomRootName())); - - $this->_doc->appendChild($root); - - $this->addArrayElements($root, $array); + $this->createDomDocument($array); return $this->_doc->saveXML(); } - - /** - * Converts arrays to DOMDocument elements - * - * @param DOMElement $parent - * @param array $array - */ - protected function addArrayElements(DOMElement $parent, $array = []) - { - if (is_array($array)) { - foreach ($array as $name => $value) { - if (!is_array($value)) { - // Create an XML element - $node = $this->createElement($name, $value); - $parent->appendChild($node); - } else { - - if (array_key_exists('@value', $value)) { - $cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false; - $attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : []; - - if (!is_array($value['@value'])) { - // Create an XML element - $node = $this->createElement($name, $value['@value'], $cdata, $attributes); - $parent->appendChild($node); - } else { - // Create an empty XML element 'container' - $node = $this->createElement($name, null); - - foreach ($attributes as $attribute_name => $attribute_value) { - $node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); - } - - $parent->appendChild($node); - - // Add all the elements within the array to the 'container' - $this->addArrayElements($node, $value['@value']); - } - } else { - // Create an empty XML element 'container' - $node = $this->createElement($name, null); - $parent->appendChild($node); - - // Add all the elements within the array to the 'container' - $this->addArrayElements($node, $value); - } - } - } - } - } - - /** - * Normalize a value (replace some characters) - * - * @param $value - * @return null|string - */ - protected function normalizeValue($value) - { - if ($value === true) { - return $this->getCastBooleanValueTrue(); - } - - if ($value === false) { - return $this->getCastBooleanValueFalse(); - } - - if ($value === null) { - return $this->getCastNullValue(); - } - - return $value; - } - - /** - * Normalize an attribute value (replace some characters) - * - * @param $value - * @return string - */ - protected function normalizeAttributeValue($value) - { - if ($value === true) { - return 'true'; - } - - if ($value === false) { - return 'false'; - } - - return $value; - } - - /** - * See if a value matches an integer (could be a integer within a string) - * - * @param $value - * @return bool - */ - protected function isNumericKey($value) - { - $pattern = '~^(0|[1-9][0-9]*)$~ux'; - - return preg_match($pattern, $value) === 1; - } - - /** - * Creates an element for DOMDocument - * - * @param $name - * @param null|string $value - * @param bool $cdata - * @param array $attributes - * @return DOMElement - */ - protected function createElement($name, $value = null, $cdata = false, $attributes = []) - { - $name = $this->createValidTagName($name); - - if ($cdata === true) { - $element = $this->_doc->createElement($name); - $element->appendChild($this->_doc->createCDATASection($value)); - - foreach ($attributes as $attribute_name => $attribute_value) { - $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); - } - - return $element; - } - - $element = $this->_doc->createElement($name, $this->normalizeValue($value)); - - foreach ($attributes as $attribute_name => $attribute_value) { - $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); - } - - return $element; - } - - /** - * Creates a valid tag name - * - * @param null|string $name - * @return string - */ - protected function createValidTagName($name = null) - { - if (empty($name) || $this->isNumericKey($name)) { - $key = $name; - - if ($this->isValidXmlTag($this->getCustomTagName())) { - $name = $this->getCustomTagName(); - } else { - $name = $this->transformTagName($this->getDefaultTagName()); - } - - if ($this->getNumericTagSuffix() !== null) { - $name = $name.(string) $this->getNumericTagSuffix().$key; - } - return $name; - } - - if (!$this->isValidXmlTag($name)) { - $name = $this->replaceInvalidTagChars($name); - - if (!self::hasValidXmlTagStartingChar($name)) { - $name = $this->prefixInvalidTagStartingChar($name); - } - } - return $this->transformTagName($name); - } - - /** - * If a tag has an invalid starting character, use an underscore as prefix - * - * @param $value - * @return string - */ - protected function prefixInvalidTagStartingChar($value) - { - return '_'.substr($value, 1); - } - - /** - * Replace invalid tag characters - * - * @param $value - * @return null|string|string[] - */ - protected function replaceInvalidTagChars($value) - { - $pattern = ''; - for ($i = 0; $i < strlen($value); $i++) { - if (!self::isValidXmlTagChar($value[$i])) { - $pattern .= "\\$value[$i]"; - } - } - - if (!empty($pattern)) { - $value = preg_replace("/[{$pattern}]/", $this->getSeparator(), $value); - } - return $value; - } - - /** - * Creates a valid root name - * - * @param null|string $name - * @return string - */ - protected function createValidRootName($name = null) - { - if (is_string($name)) { - $name = preg_replace("/[^_a-zA-Z0-9]/", $this->getSeparator(), $name); - } - if ($this->isValidXmlTag($name)) { - return $name; - } - return $this->transformTagName($this->getDefaultRootName()); - } - - /** - * Transforms a tag name (only when specified) - * - * @param null|string $name - * @return null|string - */ - protected function transformTagName($name = null) - { - switch ($this->getTransformTags()) { - case self::LOWERCASE: { - return strtolower($name); - } - case self::UPPERCASE: { - return strtoupper($name); - } - default: { - return $name; - } - } - } } diff --git a/src/Traits/DomDocumentBuilder.php b/src/Traits/DomDocumentBuilder.php new file mode 100644 index 0000000..e85db9b --- /dev/null +++ b/src/Traits/DomDocumentBuilder.php @@ -0,0 +1,267 @@ +_doc = new DOMDocument($this->getVersion(), $this->getEncoding()); + $this->_doc->formatOutput = $this->getFormatOutput(); + + $root = $this->_doc->createElement($this->createValidRootName($this->getCustomRootName())); + + $this->_doc->appendChild($root); + + $this->addArrayElements($root, $array); + } + + /** + * Converts arrays to DOMDocument elements + * + * @param DOMElement $parent + * @param array $array + */ + protected function addArrayElements(DOMElement $parent, $array = []) + { + if (is_array($array)) { + foreach ($array as $name => $value) { + if (!is_array($value)) { + // Create an XML element + $node = $this->createXmlElement($name, $value); + $parent->appendChild($node); + } else { + + if (array_key_exists('@value', $value)) { + $cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false; + $attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : []; + + if (!is_array($value['@value'])) { + // Create an XML element + $node = $this->createXmlElement($name, $value['@value'], $cdata, $attributes); + $parent->appendChild($node); + } else { + // Create an empty XML element 'container' + $node = $this->createXmlElement($name, null); + + foreach ($attributes as $attribute_name => $attribute_value) { + $node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); + } + + $parent->appendChild($node); + + // Add all the elements within the array to the 'container' + $this->addArrayElements($node, $value['@value']); + } + } else { + // Create an empty XML element 'container' + $node = $this->createXmlElement($name, null); + $parent->appendChild($node); + + // Add all the elements within the array to the 'container' + $this->addArrayElements($node, $value); + } + } + } + } + } + + /** + * Normalize a value (replace some characters) + * + * @param $value + * @return null|string + */ + protected function normalizeValue($value) + { + if ($value === true) { + return $this->getCastBooleanValueTrue(); + } + + if ($value === false) { + return $this->getCastBooleanValueFalse(); + } + + if ($value === null) { + return $this->getCastNullValue(); + } + + return $value; + } + + /** + * Normalize an attribute value (replace some characters) + * + * @param $value + * @return string + */ + protected function normalizeAttributeValue($value) + { + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + return $value; + } + + /** + * See if a value matches an integer (could be a integer within a string) + * + * @param $value + * @return bool + */ + protected function isNumericKey($value) + { + $pattern = '~^(0|[1-9][0-9]*)$~ux'; + + return preg_match($pattern, $value) === 1; + } + + /** + * Creates an element for DOMDocument + * + * @param $name + * @param null|string $value + * @param bool $cdata + * @param array $attributes + * @return DOMElement + */ + protected function createXmlElement($name, $value = null, $cdata = false, $attributes = []) + { + $name = $this->createValidTagName($name); + + if ($cdata === true) { + $element = $this->_doc->createElement($name); + $element->appendChild($this->_doc->createCDATASection($value)); + + foreach ($attributes as $attribute_name => $attribute_value) { + $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); + } + + return $element; + } + + $element = $this->_doc->createElement($name, $this->normalizeValue($value)); + + foreach ($attributes as $attribute_name => $attribute_value) { + $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); + } + + return $element; + } + + /** + * Creates a valid tag name + * + * @param null|string $name + * @return string + */ + protected function createValidTagName($name = null) + { + if (empty($name) || $this->isNumericKey($name)) { + $key = $name; + + if ($this->isValidXmlTag($this->getCustomTagName())) { + $name = $this->getCustomTagName(); + } else { + $name = $this->transformTagName($this->getDefaultTagName()); + } + + if ($this->getNumericTagSuffix() !== null) { + $name = $name.(string) $this->getNumericTagSuffix().$key; + } + return $name; + } + + if (!$this->isValidXmlTag($name)) { + $name = $this->replaceInvalidTagChars($name); + + if (!self::hasValidXmlTagStartingChar($name)) { + $name = $this->prefixInvalidTagStartingChar($name); + } + } + return $this->transformTagName($name); + } + + /** + * If a tag has an invalid starting character, use an underscore as prefix + * + * @param $value + * @return string + */ + protected function prefixInvalidTagStartingChar($value) + { + return '_'.substr($value, 1); + } + + /** + * Replace invalid tag characters + * + * @param $value + * @return null|string|string[] + */ + protected function replaceInvalidTagChars($value) + { + $pattern = ''; + for ($i = 0; $i < strlen($value); $i++) { + if (!self::isValidXmlTagChar($value[$i])) { + $pattern .= "\\$value[$i]"; + } + } + + if (!empty($pattern)) { + $value = preg_replace("/[{$pattern}]/", $this->getSeparator(), $value); + } + return $value; + } + + /** + * Creates a valid root name + * + * @param null|string $name + * @return string + */ + protected function createValidRootName($name = null) + { + if (is_string($name)) { + $name = preg_replace("/[^_a-zA-Z0-9]/", $this->getSeparator(), $name); + } + if ($this->isValidXmlTag($name)) { + return $name; + } + return $this->transformTagName($this->getDefaultRootName()); + } + + /** + * Transforms a tag name (only when specified) + * + * @param null|string $name + * @return null|string + */ + protected function transformTagName($name = null) + { + switch ($this->getTransformTags()) { + case self::LOWERCASE: { + return strtolower($name); + } + case self::UPPERCASE: { + return strtoupper($name); + } + default: { + return $name; + } + } + } +} \ No newline at end of file