XmlUtil.php 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <?php
  2. namespace NavOnlineInvoice;
  3. class XmlUtil {
  4. /**
  5. * Add elements from array to XML node
  6. *
  7. * @param \SimpleXMLElement $xmlNode
  8. * @param string $name
  9. * @param array $data
  10. */
  11. public static function addChildArray(\SimpleXMLElement $xmlNode, $name, $data) {
  12. $isSeqArray = self::isSequentialArray($data);
  13. $node = $isSeqArray ? $xmlNode : $xmlNode->addChild($name);
  14. foreach ($data as $key => $value) {
  15. $childName = $isSeqArray ? $name : $key;
  16. if (is_array($value)) {
  17. self::addChildArray($node, $childName, $value);
  18. } else {
  19. // NOTE: addChild($childName, $value) does not escape the "&" sign,
  20. // see: https://stackoverflow.com/questions/552957/rationale-behind-simplexmlelements-handling-of-text-values-in-addchild-and-adda
  21. // and: https://github.com/pzs/nav-online-invoice/issues/34
  22. // NOTE 2: This solution escape the "&" sing and allows multiple children with the same tag name, works from PHP 5.2
  23. $node->addChild($childName)[0] = $value;
  24. }
  25. }
  26. }
  27. /**
  28. * Returns true, if it's a sequantial array (keys are numeric)
  29. *
  30. * Source: https://stackoverflow.com/a/173479
  31. *
  32. * @param array $arr
  33. * @return boolean
  34. */
  35. private static function isSequentialArray(array $arr) {
  36. if (array() === $arr) {
  37. return true;
  38. }
  39. return array_keys($arr) === range(0, count($arr) - 1);
  40. }
  41. /**
  42. * Remove namespaces from XML elements
  43. *
  44. * @param \SimpleXMLElement $xmlNode
  45. * @return \SimpleXMLElement $xmlNode
  46. */
  47. public static function removeNamespaces(\SimpleXMLElement $xmlNode) {
  48. $xmlString = $xmlNode->asXML();
  49. $cleanedXmlString = self::removeNamespacesFromXmlString($xmlString);
  50. $cleanedXmlNode = simplexml_load_string($cleanedXmlString);
  51. return $cleanedXmlNode;
  52. }
  53. /**
  54. * Remove namespaces from XML string
  55. *
  56. * @param string $xmlString
  57. * @return string $xmlString
  58. */
  59. public static function removeNamespacesFromXmlString($xmlString) {
  60. return preg_replace('/(<\/|<)[a-z0-9]+:([a-z0-9]+[ =>])/i', '$1$2', $xmlString);
  61. }
  62. }