2010-10-26 3 views
6

У меня есть объединенный xml с корневым элементом и несколькими дочерними элементами элемента. Что-то вроде этогоСплит XML в PHP

<root> 
    <item>test1</item> 
    <item>test2</item> 
</root> 

То, что я хочу, это простой способ для разбора XML и создать массив строк из XML-элементов.

$arrXml[0] = '<item>test1</item>'; 
$arrXml[1] = '<item>test2</item>'; 

Я ищу элегантное решение, а не решение.

+0

Я не понимаю, как это уместно? У меня есть особая задача с этим конкретным решением. Я не хочу, чтобы картина могла быть изменена. Я считаю, что я был достаточно ясен в требованиях. – danidacar

+0

@user это просто звучит как действительно глупая идея. –

+0

Я не могу поверить, что вы проголосовали за меня за то, что вы не разделили более общую картину, даже если у вас есть опыт в развитии. Я прошу ясно, и мне не нужен моральный урок. Также, если вам действительно нужно знать, что 3-я сторона отправляет большой XML-файл. Мне нужно проанализировать файл и отправить каждому клиенту часть, в которой он нуждается, и как xml. – danidacar

ответ

7

Хорошо, как уже упоминалось в комментариях к вашему вопросу Я не уверен, что это действительно то, что вы должны делать, но так как я не могу утверждать SimpleXml и не хочу, чтобы люди думали, что это единственный способ, вот как сделать это

с DOM:

$arrXml = array(); 
$dom = new DOMDocument; 
$dom->loadXML($xml); 
foreach($dom->getElementsByTagName('item') as $item) { 
    $arrXml[] = $dom->saveXML($item); 
} 
print_r($arrXml); 

с XMLReader:

$arrXml = array(); 
$reader = new XmlReader; 
$reader->xml($xml); 
while($reader->read()) { 
    if($reader->localName === 'item' && $reader->nodeType === 1) { 
     $arrXml[] = $reader->readOuterXml(); 
    } 
} 
print_r($arrXml); 

и XMLParser*:

xml_parse_into_struct(xml_parser_create(), $xml, $nodes); 
$xmlArr = array(); 
foreach($nodes as $node) { 
    if($node['tag'] === 'ITEM') { 
     $arrXml[] = "<item>{$node['value']}</item>"; 
    } 
} 
print_r($arrXml); 

* это также может быть сделано с помощью функции обратного вызова срабатывает, когда ЭЛЕМЕНТ элемент встречается. Будет больше кода, но он довольно гибкий.

Обратите внимание, что все перечисленное может потребоваться некоторые настройки в зависимости от вашего реального XML.


Учитывая, что XML в вашем вопросе (который, скорее всего, только в качестве примера) грязь простой и хорошо определены, вы можете также использовать explode():

$arrXml = array_map('trim', 
    array_filter(
     explode(PHP_EOL, $xml), 
     function($line) { return substr($line, 0, 6) === '<item>'; } 
)); 
print_r($arrXml); 

или регулярное выражение (читай ниже условия)

preg_match_all('#<item>.*</item>#', $xml, $arrXml); 
print_r($arrXml[0]); 

Отказ от ответственности Теперь, просто чтобы убедиться, что вы не начинаете анализировать XML с Regex или Expl ода на регулярной основе: последние два подхода возможны только в том случае, если ваша разметка действительно четко определена, как вы ее показываете.

+0

Вы не упомянули SimpleXmlElement, он может обращаться к xpath. Но, по моему опыту, метод asXml() отлично не обрабатывает пространства имен. – xmedeko

1

Вы посмотрели SimpleXML?

Например:

$string = " 
<root> 
    <item>test1</item> 
    <item>test2</item> 
</root> 
"; 

$xml = simplexml_load_string($string); 
+0

Это не даст ему того, о чем он просит. Тем не менее, я не уверен, что то, что он просит, это хорошая идея. –

+0

@Pekka - да, я знаю, но он хочет, чтобы элегантное решение для синтаксического разбора XML и simpleXML было именно этим (imo). Слишком большой запас за ошибку, иначе – robjmills

+1

Это первые шаги, я согласен ... но остальное? – danidacar

2

Есть некоторые хорошие примеры кода в комментариях SimpleXml manual page. Я уверен, что вы можете сделать что-то от objectsIntoArray().

Смежные вопросы