#php #xml #simplexml
#php #xml #симплексml
Вопрос:
У меня есть простой xml-файл с одним или несколькими узлами, например:
lt;?xml version='1.0' standalone='yes'?gt; lt;nodesgt; lt;nodegt; lt;valuegt;Val1lt;/valuegt; lt;/nodegt; lt;/nodesgt;
Можно ли, используя simplexml_load_string()
функцию, для файла с одним узлом (как указано выше) получить:
SimpleXMLElement Object ( [node] =gt; Array ( [0] =gt; SimpleXMLElement Object ( [value] =gt; Val1 ) ) )
с ключом [0], как для xml-файла с большим количеством узлов, а не:
SimpleXMLElement Object ( [node] =gt; SimpleXMLElement Object ( [value] =gt; Val1 ) )
Потому что затем мне нужно преобразовать его в массив с той же глубиной, будь то из файла с одним или несколькими узлами
Ответ №1:
SimpleXML уже делает то , что вы хотите — разница между ними заключается только в выводе print_r
, который показывает наиболее краткий способ доступа к элементам, а не единственный способ.
В частности, $xml-gt;node-gt;value
и $xml-gt;node[0]-gt;value[0]
всегда может использоваться для ссылки на один и тот же узел, и foreach ( $xml-gt;node as $node )
всегда работает, даже если есть только один соответствующий узел.
Вот почему, как правило, плохая идея «вслепую» конвертировать XML — структуру в массив PHP-вместо этого используйте foreach
циклы и доступ к свойствам для извлечения любой необходимой вам информации.
Вы можете попробовать это сами с помощью этого кода:
// Single node $xml1 = lt;lt;lt;XML lt;?xml version='1.0' standalone='yes'?gt; lt;nodesgt; lt;nodegt; lt;valuegt;Val1lt;/valuegt; lt;/nodegt; lt;/nodesgt; XML; $sx1 = simplexml_load_string($xml1); print_r($sx1); // misleading! echo $sx1-gt;node-gt;value, PHP_EOL; echo $sx1-gt;node-gt;value[0], PHP_EOL; echo $sx1-gt;node[0]-gt;value[0], PHP_EOL; echo $sx1-gt;node[0]-gt;value, PHP_EOL; foreach ( $sx1-gt;node as $node ) { echo $node-gt;value, PHP_EOL; } // Two nodes with same name $xml2 = lt;lt;lt;XML lt;?xml version='1.0' standalone='yes'?gt; lt;nodesgt; lt;nodegt; lt;valuegt;Val1lt;/valuegt; lt;/nodegt; lt;nodegt; lt;valuegt;Val2lt;/valuegt; lt;/nodegt; lt;/nodesgt; XML; $sx2 = simplexml_load_string($xml2); print_r($sx2); // misleading! echo $sx2-gt;node-gt;value, PHP_EOL; echo $sx2-gt;node[0]-gt;value, PHP_EOL; echo $sx2-gt;node[0]-gt;value[0], PHP_EOL; echo $sx2-gt;node-gt;value[0], PHP_EOL; foreach ( $sx2-gt;node as $node ) { echo $node-gt;value, PHP_EOL; }
Комментарии:
1. Спасибо, я все понимаю. Проблема начинается как раз тогда, когда я пытаюсь преобразовать ее в массивы… У меня есть другие данные в массивах, и мне нужно сравнить/сопоставить их с этими данными из xml-файла. Оптимально ли использовать массивы, с одной стороны, и объект, с другой, или лучше преобразовать его в один и тот же тип?
2. Я думал о массивах, потому что функции array_intersect_key (), array_change_key_case() и т. Д. были мне очень полезны.
3. Использование массивов-это нормально, но не ожидайте, что вы напишете функцию, которая может преобразовать любой XML-документ в полезный массив, потому что существует так много способов структурирования XML и так много деталей, которые вас, вероятно, не волнуют. Вместо этого посмотрите на конкретный документ, который у вас есть, и просмотрите его фрагменты, которые вас интересуют, выстраивая их в свою собственную структуру массива. Например, в этом примере вы можете пройти по узлам и создать что-то вроде
['Val1', 'Val2]
или[ ['Value' =gt; 'Val1'], ['Value' =gt; 'Val2'] ]
.