|
2 | 2 |
|
3 | 3 | namespace RefactorStudio\PhpArrayToXml;
|
4 | 4 |
|
5 |
| -use DOMDocument; |
6 |
| -use DOMElement; |
7 | 5 | use RefactorStudio\PhpArrayToXml\Lib\XmlPatterns;
|
| 6 | +use RefactorStudio\PhpArrayToXml\Traits\DomDocumentBuilder; |
8 | 7 |
|
9 | 8 | class PhpArrayToXml
|
10 | 9 | {
|
| 10 | + use DomDocumentBuilder; |
| 11 | + |
11 | 12 | const LOWERCASE = 'lowercase';
|
12 | 13 | const UPPERCASE = 'uppercase';
|
13 | 14 |
|
@@ -387,256 +388,8 @@ public static function isValidXmlTag($value = null)
|
387 | 388 | */
|
388 | 389 | public function toXmlString($array = [])
|
389 | 390 | {
|
390 |
| - $this->_doc = new DOMDocument($this->getVersion(), $this->getEncoding()); |
391 |
| - $this->_doc->formatOutput = $this->getFormatOutput(); |
392 |
| - |
393 |
| - $root = $this->_doc->createElement($this->createValidRootName($this->getCustomRootName())); |
394 |
| - |
395 |
| - $this->_doc->appendChild($root); |
396 |
| - |
397 |
| - $this->addArrayElements($root, $array); |
| 391 | + $this->createDomDocument($array); |
398 | 392 |
|
399 | 393 | return $this->_doc->saveXML();
|
400 | 394 | }
|
401 |
| - |
402 |
| - /** |
403 |
| - * Converts arrays to DOMDocument elements |
404 |
| - * |
405 |
| - * @param DOMElement $parent |
406 |
| - * @param array $array |
407 |
| - */ |
408 |
| - protected function addArrayElements(DOMElement $parent, $array = []) |
409 |
| - { |
410 |
| - if (is_array($array)) { |
411 |
| - foreach ($array as $name => $value) { |
412 |
| - if (!is_array($value)) { |
413 |
| - // Create an XML element |
414 |
| - $node = $this->createElement($name, $value); |
415 |
| - $parent->appendChild($node); |
416 |
| - } else { |
417 |
| - |
418 |
| - if (array_key_exists('@value', $value)) { |
419 |
| - $cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false; |
420 |
| - $attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : []; |
421 |
| - |
422 |
| - if (!is_array($value['@value'])) { |
423 |
| - // Create an XML element |
424 |
| - $node = $this->createElement($name, $value['@value'], $cdata, $attributes); |
425 |
| - $parent->appendChild($node); |
426 |
| - } else { |
427 |
| - // Create an empty XML element 'container' |
428 |
| - $node = $this->createElement($name, null); |
429 |
| - |
430 |
| - foreach ($attributes as $attribute_name => $attribute_value) { |
431 |
| - $node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); |
432 |
| - } |
433 |
| - |
434 |
| - $parent->appendChild($node); |
435 |
| - |
436 |
| - // Add all the elements within the array to the 'container' |
437 |
| - $this->addArrayElements($node, $value['@value']); |
438 |
| - } |
439 |
| - } else { |
440 |
| - // Create an empty XML element 'container' |
441 |
| - $node = $this->createElement($name, null); |
442 |
| - $parent->appendChild($node); |
443 |
| - |
444 |
| - // Add all the elements within the array to the 'container' |
445 |
| - $this->addArrayElements($node, $value); |
446 |
| - } |
447 |
| - } |
448 |
| - } |
449 |
| - } |
450 |
| - } |
451 |
| - |
452 |
| - /** |
453 |
| - * Normalize a value (replace some characters) |
454 |
| - * |
455 |
| - * @param $value |
456 |
| - * @return null|string |
457 |
| - */ |
458 |
| - protected function normalizeValue($value) |
459 |
| - { |
460 |
| - if ($value === true) { |
461 |
| - return $this->getCastBooleanValueTrue(); |
462 |
| - } |
463 |
| - |
464 |
| - if ($value === false) { |
465 |
| - return $this->getCastBooleanValueFalse(); |
466 |
| - } |
467 |
| - |
468 |
| - if ($value === null) { |
469 |
| - return $this->getCastNullValue(); |
470 |
| - } |
471 |
| - |
472 |
| - return $value; |
473 |
| - } |
474 |
| - |
475 |
| - /** |
476 |
| - * Normalize an attribute value (replace some characters) |
477 |
| - * |
478 |
| - * @param $value |
479 |
| - * @return string |
480 |
| - */ |
481 |
| - protected function normalizeAttributeValue($value) |
482 |
| - { |
483 |
| - if ($value === true) { |
484 |
| - return 'true'; |
485 |
| - } |
486 |
| - |
487 |
| - if ($value === false) { |
488 |
| - return 'false'; |
489 |
| - } |
490 |
| - |
491 |
| - return $value; |
492 |
| - } |
493 |
| - |
494 |
| - /** |
495 |
| - * See if a value matches an integer (could be a integer within a string) |
496 |
| - * |
497 |
| - * @param $value |
498 |
| - * @return bool |
499 |
| - */ |
500 |
| - protected function isNumericKey($value) |
501 |
| - { |
502 |
| - $pattern = '~^(0|[1-9][0-9]*)$~ux'; |
503 |
| - |
504 |
| - return preg_match($pattern, $value) === 1; |
505 |
| - } |
506 |
| - |
507 |
| - /** |
508 |
| - * Creates an element for DOMDocument |
509 |
| - * |
510 |
| - * @param $name |
511 |
| - * @param null|string $value |
512 |
| - * @param bool $cdata |
513 |
| - * @param array $attributes |
514 |
| - * @return DOMElement |
515 |
| - */ |
516 |
| - protected function createElement($name, $value = null, $cdata = false, $attributes = []) |
517 |
| - { |
518 |
| - $name = $this->createValidTagName($name); |
519 |
| - |
520 |
| - if ($cdata === true) { |
521 |
| - $element = $this->_doc->createElement($name); |
522 |
| - $element->appendChild($this->_doc->createCDATASection($value)); |
523 |
| - |
524 |
| - foreach ($attributes as $attribute_name => $attribute_value) { |
525 |
| - $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); |
526 |
| - } |
527 |
| - |
528 |
| - return $element; |
529 |
| - } |
530 |
| - |
531 |
| - $element = $this->_doc->createElement($name, $this->normalizeValue($value)); |
532 |
| - |
533 |
| - foreach ($attributes as $attribute_name => $attribute_value) { |
534 |
| - $element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value)); |
535 |
| - } |
536 |
| - |
537 |
| - return $element; |
538 |
| - } |
539 |
| - |
540 |
| - /** |
541 |
| - * Creates a valid tag name |
542 |
| - * |
543 |
| - * @param null|string $name |
544 |
| - * @return string |
545 |
| - */ |
546 |
| - protected function createValidTagName($name = null) |
547 |
| - { |
548 |
| - if (empty($name) || $this->isNumericKey($name)) { |
549 |
| - $key = $name; |
550 |
| - |
551 |
| - if ($this->isValidXmlTag($this->getCustomTagName())) { |
552 |
| - $name = $this->getCustomTagName(); |
553 |
| - } else { |
554 |
| - $name = $this->transformTagName($this->getDefaultTagName()); |
555 |
| - } |
556 |
| - |
557 |
| - if ($this->getNumericTagSuffix() !== null) { |
558 |
| - $name = $name.(string) $this->getNumericTagSuffix().$key; |
559 |
| - } |
560 |
| - return $name; |
561 |
| - } |
562 |
| - |
563 |
| - if (!$this->isValidXmlTag($name)) { |
564 |
| - $name = $this->replaceInvalidTagChars($name); |
565 |
| - |
566 |
| - if (!self::hasValidXmlTagStartingChar($name)) { |
567 |
| - $name = $this->prefixInvalidTagStartingChar($name); |
568 |
| - } |
569 |
| - } |
570 |
| - return $this->transformTagName($name); |
571 |
| - } |
572 |
| - |
573 |
| - /** |
574 |
| - * If a tag has an invalid starting character, use an underscore as prefix |
575 |
| - * |
576 |
| - * @param $value |
577 |
| - * @return string |
578 |
| - */ |
579 |
| - protected function prefixInvalidTagStartingChar($value) |
580 |
| - { |
581 |
| - return '_'.substr($value, 1); |
582 |
| - } |
583 |
| - |
584 |
| - /** |
585 |
| - * Replace invalid tag characters |
586 |
| - * |
587 |
| - * @param $value |
588 |
| - * @return null|string|string[] |
589 |
| - */ |
590 |
| - protected function replaceInvalidTagChars($value) |
591 |
| - { |
592 |
| - $pattern = ''; |
593 |
| - for ($i = 0; $i < strlen($value); $i++) { |
594 |
| - if (!self::isValidXmlTagChar($value[$i])) { |
595 |
| - $pattern .= "\\$value[$i]"; |
596 |
| - } |
597 |
| - } |
598 |
| - |
599 |
| - if (!empty($pattern)) { |
600 |
| - $value = preg_replace("/[{$pattern}]/", $this->getSeparator(), $value); |
601 |
| - } |
602 |
| - return $value; |
603 |
| - } |
604 |
| - |
605 |
| - /** |
606 |
| - * Creates a valid root name |
607 |
| - * |
608 |
| - * @param null|string $name |
609 |
| - * @return string |
610 |
| - */ |
611 |
| - protected function createValidRootName($name = null) |
612 |
| - { |
613 |
| - if (is_string($name)) { |
614 |
| - $name = preg_replace("/[^_a-zA-Z0-9]/", $this->getSeparator(), $name); |
615 |
| - } |
616 |
| - if ($this->isValidXmlTag($name)) { |
617 |
| - return $name; |
618 |
| - } |
619 |
| - return $this->transformTagName($this->getDefaultRootName()); |
620 |
| - } |
621 |
| - |
622 |
| - /** |
623 |
| - * Transforms a tag name (only when specified) |
624 |
| - * |
625 |
| - * @param null|string $name |
626 |
| - * @return null|string |
627 |
| - */ |
628 |
| - protected function transformTagName($name = null) |
629 |
| - { |
630 |
| - switch ($this->getTransformTags()) { |
631 |
| - case self::LOWERCASE: { |
632 |
| - return strtolower($name); |
633 |
| - } |
634 |
| - case self::UPPERCASE: { |
635 |
| - return strtoupper($name); |
636 |
| - } |
637 |
| - default: { |
638 |
| - return $name; |
639 |
| - } |
640 |
| - } |
641 |
| - } |
642 | 395 | }
|
0 commit comments