|
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