Overview

Namespaces

  • Scopus
    • Exception
    • Response
    • Util

Classes

  • Scopus\Response\AbstractAuthor
  • Scopus\Response\AbstractCoredata
  • Scopus\Response\AbstractItem
  • Scopus\Response\Abstracts
  • Scopus\Response\Affiliation
  • Scopus\Response\Author
  • Scopus\Response\AuthorGroup
  • Scopus\Response\AuthorName
  • Scopus\Response\AuthorProfile
  • Scopus\Response\BaseLinks
  • Scopus\Response\Bibrecord
  • Scopus\Response\BibrecordHead
  • Scopus\Response\Correspondence
  • Scopus\Response\CorrespondencePerson
  • Scopus\Response\Entry
  • Scopus\Response\EntryAuthor
  • Scopus\Response\EntryLinks
  • Scopus\Response\SearchLinks
  • Scopus\Response\SearchResults
  • Scopus\Response\Source
  • Scopus\ScopusApi
  • Scopus\SearchQuery
  • Scopus\Util\XmlUtil

Interfaces

  • Scopus\Response\IAbstract
  • Scopus\Response\IAuthor
  • Scopus\Response\IAuthorName

Exceptions

  • Scopus\Exception\JsonException
  • Scopus\Exception\XmlException
  • Overview
  • Namespace
  • Class
 1: <?php
 2: 
 3: namespace Scopus\Util;
 4: 
 5: use SimpleXMLElement;
 6: 
 7: class XmlUtil
 8: {
 9:     public static function toArray(SimpleXMLElement $xml, array $options = [])
10:     {
11:         $defaults = array(
12:             'namespaceSeparator' => ':',//you may want this to be something other than a colon
13:             'attributePrefix' => '@',   //to distinguish between attributes and nodes with the same name
14:             'alwaysArray' => array(),   //array of xml tag names which should always become arrays
15:             'autoArray' => true,        //only create arrays for tags which appear more than once
16:             'textContent' => '$',       //key used for the text content of elements
17:             'autoText' => true,         //skip textContent key if node has no attributes or child nodes
18:             'keySearch' => false,       //optional search and replace on tag and attribute names
19:             'keyReplace' => false       //replace values for above search values (as passed to str_replace())
20:         );
21:         $options = array_merge($defaults, $options);
22:         $namespaces = $xml->getDocNamespaces();
23:         $namespaces[''] = null; //add base (empty) namespace
24: 
25:         //get attributes from all namespaces
26:         $attributesArray = array();
27:         foreach ($namespaces as $prefix => $namespace) {
28:             foreach ($xml->attributes($namespace) as $attributeName => $attribute) {
29:                 //replace characters in attribute name
30:                 if ($options['keySearch']) $attributeName =
31:                     str_replace($options['keySearch'], $options['keyReplace'], $attributeName);
32:                 $attributeKey = $options['attributePrefix']
33:                     . ($prefix ? $prefix . $options['namespaceSeparator'] : '')
34:                     . $attributeName;
35:                 $attributesArray[$attributeKey] = (string)$attribute;
36:             }
37:         }
38: 
39:         //get child nodes from all namespaces
40:         $tagsArray = array();
41:         foreach ($namespaces as $prefix => $namespace) {
42:             foreach ($xml->children($namespace) as $childXml) {
43:                 //recurse into child nodes
44:                 $childArray = self::toArray($childXml, $options);
45:                 list($childTagName, $childProperties) = each($childArray);
46: 
47:                 //replace characters in tag name
48:                 if ($options['keySearch']) $childTagName =
49:                     str_replace($options['keySearch'], $options['keyReplace'], $childTagName);
50:                 //add namespace prefix, if any
51:                 if ($prefix) $childTagName = $prefix . $options['namespaceSeparator'] . $childTagName;
52: 
53:                 if (!isset($tagsArray[$childTagName])) {
54:                     //only entry with this key
55:                     //test if tags of this type should always be arrays, no matter the element count
56:                     $tagsArray[$childTagName] =
57:                         in_array($childTagName, $options['alwaysArray']) || !$options['autoArray']
58:                             ? array($childProperties) : $childProperties;
59:                 } elseif (
60:                     is_array($tagsArray[$childTagName]) && array_keys($tagsArray[$childTagName])
61:                     === range(0, count($tagsArray[$childTagName]) - 1)
62:                 ) {
63:                     //key already exists and is integer indexed array
64:                     $tagsArray[$childTagName][] = $childProperties;
65:                 } else {
66:                     //key exists so convert to integer indexed array with previous value in position 0
67:                     $tagsArray[$childTagName] = array($tagsArray[$childTagName], $childProperties);
68:                 }
69:             }
70:         }
71: 
72:         //get text content of node
73:         $textContentArray = array();
74:         $plainText = trim((string)$xml);
75:         if ($plainText !== '') $textContentArray[$options['textContent']] = $plainText;
76: 
77:         //stick it all together
78:         $propertiesArray = !$options['autoText'] || $attributesArray || $tagsArray || ($plainText === '')
79:             ? array_merge($attributesArray, $tagsArray, $textContentArray) : $plainText;
80: 
81:         //return node as array
82:         return [$xml->getName() => $propertiesArray];
83:     }
84: }
API documentation generated by ApiGen