2014-07-09 4 views
0

Привет Я пытаюсь использовать XML-Reader для чтения динамического xml, где я не знаю имена элементов. Мне нужно использовать XML Reader, а не SimpleXML, поскольку это все, что доступно на моем сервере. Проблема, с которой я столкнулась, заключается в попытке иметь что-то, что может иметь дело с вложенными и не вложенными элементами. Мой XML выглядитPHP XMLREADER Вложенные элементы

<status> 
    <state>active</state> 
    <time>2014-07-15T04:00:00.000Z</time> 
    <output-type>archive</output-type> 
    <sources> 
<source> 
<class>audio</class> 
<channels> 
    <channel> 
     <position>left</position> 
     <average>0</average> 
     <peak>0</peak> 
    </channel> 
    <channel> 
     <position>right</position> 
     <average>1095</average> 
     <peak>1114</peak> 
    </channel> 
</channels> 
</source> 
</status> 

но также может выглядеть следующим образом:

<status>inactive</status> 

Я использую следующий код:

while ($reader->read()) { 
     if ($reader->nodeType == XMLReader::ELEMENT) { 
      $element = $reader->name; 
      //$elementarray[] = $element; 
      echo $element; 
      if ($reader->depth <1){echo"</br>";} 
     } 

     if ($reader->nodeType == XMLReader::TEXT) { 
      $value = $reader->value; 
      $valuearray[] = $value; 
      echo " : ".$value."</br>";     
     } 
    } 

Это выводит

1stElement2ndelement : text 

я не могу найти anyw ay в плохо документированном XML Reader, чтобы иметь выход

1stElement: 
2ndelement: text 

, который я могу заполнить массивом.

Любая помощь приветствуется, поскольку я новичок в PHP.

ответ

0

Не размещайте псевдо xml. Это недопустимо xml (имена элементов не могут начинаться с цифры). Это затрудняет понимание/подтверждение вашей проблемы. Доступна ли DOM? Было бы странно иметь только XMLReader, а не DOM. С DOM у вас есть Xpath, и это намного проще в использовании.

Итак, давайте предположим некоторые варианты xml.

$xml = <<<'XML' 
<options> 
    <one>1</one> 
    <two>2</two> 
</options> 
XML; 

Читатель XML читает каждый узел. Помните имя последнего узла элемента. Если текстовый узел найден и не пуст, добавьте содержимое с запоминаемым именем в массив результатов.

$reader = new XMLReader(); 
$reader->open('data:/text/plain,'.urlencode($xml)); 

$result = []; 
$element = null; 
while ($reader->read()) { 
    switch ($reader->nodeType) { 
    case XMLReader::ELEMENT : 
    $element = $reader->name; 
    break; 
    case XMLReader::TEXT : 
    $value = $reader->value; 
    if (trim($value) != '') { 
     $result[$element] = $value; 
    } 
    break; 
    } 
} 

var_dump($result); 

Выход:

array(2) { 
    ["one"]=> 
    string(1) "1" 
    ["two"]=> 
    string(1) "2" 
} 

В DOM можно просто выбрать узлы элементов в список и итерацию их:

$dom = new DOMDocument(); 
$dom->loadXml($xml); 
$xpath = new DOMXpath($dom); 

$result = []; 
foreach ($xpath->evaluate('/options/*') as $node) { 
    $result[$node->localName] = $node->nodeValue; 
} 

var_dump($result); 

Демо: https://eval.in/170803

DOMXPath: : evaluation() позволяет делать ваши выражения относительно узла контекста и получать скалярные s. Таким образом, вы в основном будете либо получать скаляр, либо список узлов, который вы можете выполнять. Результат зависит от выражения Xpath, поэтому вы всегда будете знать.

$dom = new DOMDocument(); 
$dom->loadXml($xml); 
$xpath = new DOMXpath($dom); 

foreach ($xpath->evaluate('//channels/channel') as $channel) { 
    var_dump(
    $xpath->evaluate('string(position)', $channel), 
    $xpath->evaluate('number(1095)', $channel), 
    $xpath->evaluate('number(1114)', $channel) 
); 
} 

Демо: https://eval.in/172551

+0

Спасибо, у меня не было рассматриваться DOM, но это гораздо проще. Я обновил xml, как было предложено. У меня возникают проблемы с дублирующими узлами, такими как «канал», любое предложение будет оценено по достоинству. – Kirby

+0

Вам нужно повторить их, как я сделал в примере с вариантами children. Проверьте второй аргумент метода(), это контекст. Вы можете использовать его для выражения выражения относительно узла. Я добавлю пример ответа. – ThW

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