Предотвратить слияние SimpleXML дубликатов элементов / тегов?

У меня есть некоторые нестандартные XML от Avendor с повторяющимися элементами.

SimpleXML и DOM объединяют мои теги XML. Как я могу предотвратить это?

Есть ли способ получить их в массив без их слияния?

Мой XML выглядит примерно так:


<quiz>
<settings>
<user name="joe" email="[email protected]" />
</settings>
<questions>
<multiplechoice id="1">
<directions>What is 1+1?</directions>
<answer correct="true" selected="false">2</answer>
<answer correct="false" selected="false">4</answer>
<answer correct="false" selected="true">1</answer>
<answer correct="false" selected="false">0</answer>
</multiplechoice>
<truefalse id="2">
<directions>0 > 1?</directions>
<answer correct="true" selected="false">True</answer>
<answer correct="false" selected="true">False</answer>
</truefalse>
<multiplechoice id="3">
<directions>What is 2+1?</directions>
<answer correct="true" selected="false">3</answer>
<answer correct="false" selected="false">4</answer>
<answer correct="false" selected="true">1</answer>
<answer correct="false" selected="false">0</answer>
</multiplechoice>
</questions>
</quiz>

Мой PHP такой:

$xml = new SimpleXMLElement($xmldata);

Что происходит?

Независимо от того, как я это пробую, SimpleXML объединяет <multiplechoice> элементы в единый array() как это:

[questions] => Array
(
[multiplechoice] => Array
(
[0] => Array
(
[@attributes] => Array
(
[id] => 1}
)
[directions] => What is 1+1?
[answers] => Array
(
[answer] => Array
(
[0] => 2
[1] => 4
[2] => 1
[3] => 0
)

)

)

[1] => Array
(
[@attributes] => Array
(
[id] => 3
)
[directions] => What is 2+1?
[answers] => Array
(
[answer] => Array
(
[0] => 3
[1] => 4
[2] => 1
[3] => 0
)

)

)
)
[truefalse] => Array
(
[0] => Array
(
[@attributes] => Array
(
[id] => 2}
)

[directions] => 0 > 1?
[answers] => Array
(
[answer] => Array
(
[0] => True
[1] => False
)
)
)
)
)

Что я хочу:

<multiplechoice> элементы должны быть отдельными и в начальном порядке:

[questions] => Array
(
[multiplechoice] => Array
(
[0] => Array
(
[@attributes] => Array
(
[id] => 1}
)
[directions] => What is 1+1?
[answers] => Array
(
[answer] => Array
(
[0] => 2
[1] => 4
[2] => 1
[3] => 0
)

)

)
)
[truefalse] => Array
(
[0] => Array
(
[@attributes] => Array
(
[id] => 2}
)

[directions] => 0 > 1?
[answers] => Array
(
[answer] => Array
(
[0] => True
[1] => False
)
)
)
)
[multiplechoice] => Array
(
[0] => Array
(
[@attributes] => Array
(
[id] => 3
)
[directions] => What is 2+1?
[answers] => Array
(
[answer] => Array
(
[0] => 3
[1] => 4
[2] => 1
[3] => 0
)

)

)
)
)

-1

Решение

Я не знаю какие ты делаешь с DOM, но он поддерживает порядок «из коробки» здесь:

$dom = new DOMDocument();
$dom->loadXML($xml);
$questions = $dom->getElementsByTagName('questions')->item(0);
if($questions instanceof DOMElement){
foreach($questions->childNodes as $child){
if($child instanceof DOMElement){
var_dump($child->tagName, simplexml_import_dom($child));
}
}
}

Прекрасно по порядку:

string(14) "multiplechoice"class SimpleXMLElement#4 (3) {
public $@attributes =>
array(1) {
'id' =>
string(1) "1"}
public $directions =>
string(12) "What is 1+1?"public $answer =>
array(4) {
[0] =>
string(1) "2"[1] =>
string(1) "4"[2] =>
string(1) "1"[3] =>
string(1) "0"}
}
string(9) "truefalse"class SimpleXMLElement#4 (3) {
public $@attributes =>
array(1) {
'id' =>
string(1) "2"}
public $directions =>
string(6) "0 > 1?"public $answer =>
array(2) {
[0] =>
string(4) "True"[1] =>
string(5) "False"}
}
string(14) "multiplechoice"class SimpleXMLElement#4 (3) {
public $@attributes =>
array(1) {
'id' =>
string(1) "3"}
public $directions =>
string(12) "What is 2+1?"public $answer =>
array(4) {
[0] =>
string(1) "3"[1] =>
string(1) "4"[2] =>
string(1) "1"[3] =>
string(1) "0"}
1

Другие решения

как и другие Сам я обрисовал в общих чертах, невозможно поместить древовидную структуру в массив так, как вы просите в своем вопросе.

XML — это древовидная структура, и несколько элементов с одинаковым именем могут существовать на одном уровне. то, что невозможно с массивами.

так что лучше сохранить SimpleXMLElementкак они есть. С ними гораздо удобнее работать с данными, чем с массивом.

Как бы то ни было, все же возможно создать массив из этих данных, аналогичный тому, который вы запрашиваете, но он требует особого подхода к структуре в нем. Нет общего способа справиться с этим.

Например: все дочерние элементы из вопросов на их позиции, затем набираются их имена:

$result = $xml->xpath('//questions/*');

foreach ($result as &$rebuild) {
$rebuild = [$rebuild->getName() => $rebuild];
}
unset($rebuild);
$result = ['questions' => $result];

$array  = json_decode(json_encode($result), true);

В результате получается массив в таком формате, с которым, я думаю, не очень удобно иметь дело:

Array
(
[questions] => Array
(
[0] => Array
(
[multiplechoice] => Array
(
[@attributes] => Array
(
[id] => 1
)

[directions] => What is 1+1?
[answer] => Array
(
[0] => 2
[1] => 4
[2] => 1
[3] => 0
)

)

)

[1] => Array
(
[truefalse] => Array
(
[@attributes] => Array
(
[id] => 2
)

[directions] => 0 > 1?
[answer] => Array
(
[0] => True
[1] => False
)

)

)

[2] => Array
(
[multiplechoice] => Array
(
[@attributes] => Array
(
[id] => 3
)

[directions] => What is 2+1?
[answer] => Array
(
[0] => 3
[1] => 4
[2] => 1
[3] => 0
)

)

)

)

)
0

По вопросам рекламы [email protected]