У меня есть этот метод, который преобразует строку XML в массив PHP с различными ключами и значениями, чтобы полностью понять смысл этого XML. Однако, когда есть несколько дочерних элементов одного и того же типа, я не получаю желаемый результат из массива, и я не понимаю, как изменить метод для этого.
Вот как выглядит метод:
/**
* Converts a XML string to an array
*
* @param $xmlString
* @return array
*/
private function parseXml($xmlString)
{
$doc = new DOMDocument;
$doc->loadXML($xmlString);
$root = $doc->documentElement;
$output[$root->tagName] = $this->domnodeToArray($root, $doc);
return $output;
}
/**
* @param $node
* @param $xmlDocument
* @return array|string
*/
private function domNodeToArray($node, $xmlDocument)
{
$output = [];
switch ($node->nodeType)
{
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++)
{
$child = $node->childNodes->item($i);
$v = $this->domNodeToArray($child, $xmlDocument);
if (isset($child->tagName))
{
$t = $child->tagName;
if (!isset($output['value'][$t]))
{
$output['value'][$t] = [];
}
$output['value'][$t][] = $v;
}
else if ($v || $v === '0')
{
$output['value'] = htmlspecialchars((string)$v, ENT_XML1 | ENT_COMPAT, 'UTF-8');
}
}
if (isset($output['value']) && $node->attributes->length && !is_array($output['value']))
{
$output = ['value' => $output['value']];
}
if (!$node->attributes->length && isset($output['value']) && !is_array($output['value']))
{
$output = ['attributes' => [], 'value' => $output['value']];
}
if ($node->attributes->length)
{
$a = [];
foreach ($node->attributes as $attrName => $attrNode)
{
$a[$attrName] = (string)$attrNode->value;
}
$output['attributes'] = $a;
}
else
{
$output['attributes'] = [];
}
if (isset($output['value']) && is_array($output['value']))
{
foreach ($output['value'] as $t => $v)
{
if (is_array($v) && count($v) == 1 && $t != 'attributes')
{
$output['value'][$t] = $v[0];
}
}
}
break;
}
return $output;
}
Вот пример XML:
<?xml version="1.0" encoding="UTF-8"?>
<characters>
<character>
<name2>Sno</name2>
<friend-of>Pep</friend-of>
<since>1950-10-04</since>
<qualification>extroverted beagle</qualification>
</character>
<character>
<name2>Pep</name2>
<friend-of>Sno</friend-of>
<since>1966-08-22</since>
<qualification>bold, brash and tomboyish</qualification>
</character>
</characters>
Запуск метода и передача этого XML в качестве его параметра приведет к следующему массиву:
array:1 [▼
"characters" => array:2 [▼
"value" => array:1 [▼
"character" => array:2 [▼
0 => array:2 [▼
"value" => array:4 [▼
"name2" => array:2 [▼
"attributes" => []
"value" => "Sno"
]
"friend-of" => array:2 [▼
"attributes" => []
"value" => "Pep"
]
"since" => array:2 [▼
"attributes" => []
"value" => "1950-10-04"
]
"qualification" => array:2 [▼
"attributes" => []
"value" => "extroverted beagle"
]
]
"attributes" => []
]
1 => array:2 [▼
"value" => array:4 [▼
"name2" => array:2 [▼
"attributes" => []
"value" => "Pep"
]
"friend-of" => array:2 [▼
"attributes" => []
"value" => "Sno"
]
"since" => array:2 [▼
"attributes" => []
"value" => "1966-08-22"
]
"qualification" => array:2 [▼
"attributes" => []
"value" => "bold, brash and tomboyish"
]
]
"attributes" => []
]
]
]
"attributes" => []
]
]
То, к чему я хочу привести, это (отступ может быть неправильным):
array:1 [▼
"characters" => array:2 [▼
"value" => array:2 [▼
0 => [
"character" => array:1 [▼
"value" => array:4 [▼
"name2" => array:2 [▼
"attributes" => []
"value" => "Sno"
]
"friend-of" => array:2 [▼
"attributes" => []
"value" => "Pep"
]
"since" => array:2 [▼
"attributes" => []
"value" => "1950-10-04"
]
"qualification" => array:2 [▼
"attributes" => []
"value" => "extroverted beagle"
]
]
"attributes" => []
]
]
]
1 => array:2 [▼
"character" => array:1 [▼
"value" => array:4 [▼
"name2" => array:2 [▼
"attributes" => []
"value" => "Pep"
]
"friend-of" => array:2 [▼
"attributes" => []
"value" => "Sno"
]
"since" => array:2 [▼
"attributes" => []
"value" => "1966-08-22"
]
"qualification" => array:2 [▼
"attributes" => []
"value" => "bold, brash and tomboyish"
]
]
"attributes" => []
]
]
]
]
"attributes" => []
]
]
Итак, я хочу, чтобы ключ value
ключа characters
представлял собой массив из двух элементов, который в основном включает ключи 2 character
. Это происходит только в том случае, если в одной и той же ветви много одинаковых элементов. В настоящее время ситуация, когда ключ character
представляет собой массив с 2 элементами, в моей ситуации не работает.
Изменение метода, описанного выше, чтобы отразить мои потребности, еще не было возможно для меня, и я не уверен, какой подход я должен использовать. Изменение такого массива из экземпляра DOMDocument
кажется довольно сложным.