Разбирайте XML с помощью пространства имен с помощью SimpleXML

У меня это как xml:

<root xmlns:event="http://www.webex.com/schemas/2002/06/service/event"> <event:event> <event:sessionKey></event:sessionKey> <event:sessionName>Learn QB in Minutes</event:sessionName> <event:sessionType>9</event:sessionType> <event:hostWebExID></event:hostWebExID> <event:startDate>02/12/2009</event:startDate> <event:endDate>02/12/2009</event:endDate> <event:timeZoneID>11</event:timeZoneID> <event:duration>30</event:duration> <event:description></event:description> <event:status>NOT_INPROGRESS</event:status> <event:panelists></event:panelists> <event:listStatus>PUBLIC</event:listStatus> </event:event> ... </root> 

Как я могу пройти через все события: узлы событий и отображение, например, всего события: SessionKey?

Это не работает:

 $xml = new SimpleXMLElement($r); $xml->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event'); foreach($xml->xpath('//e:event') as $event) { var_export($event->xpath('//e:sessionKey')); } 

он работает без registerXPathNamespace и полного префикса пространства имен в запросах xpath:

 $xml = new SimpleXMLElement($r); foreach($xml->xpath('//event:event') as $event) { var_export($event->xpath('event:sessionKey')); } 

Вы должны зарегистрировать пространство имен для каждого объекта simpleXMLElement, который используете.

 $xml = new SimpleXMLElement($r); $xml->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event'); foreach($xml->xpath('//e:event') as $event) { $event->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event'); var_export($event->xpath('//e:sessionKey')); } 

Пространство имен также должно быть объявлено где-то в файле xml.

 <event:event xmlns:event="http://www.webex.com/schemas/2002/06/service/event"> ... 

Описанный метод ax также работает. Вы можете пропустить registerXPathNamespace, если знаете, что xml-файл всегда будет использовать тот же префикс.

здесь альтернатива, которая сработала для меня.

 $xml = simplexml_load_string($r); $ns = $xml->getNamespaces(true); foreach ($xml->children($ns['event'])->event as $skey) { $sessionKey = $skey->children($ns['event'])->sessionKey; echo $sessionKey; } 

Другой подход заключается в использовании SimpleXML для синтаксического анализа и DOMDocument для манипулирования / доступа, который вообще обходит проблемы с именами:

 $xml = new SimpleXMLElement($r); $xml = dom_import_simplexml($xml); $nodelist= $xml->getElementsByTagName('event'); for($i = 0; $i < $nodelist->length; $i++) { $sessions = $nodelist->item($i)->getElementsByTagName('sessionKey'); echo $sessions->item(0)->nodeValue; } 

Использование registerXPathNamespace а затем вызов xpath самом деле не работал для меня. Мне пришлось пойти с решением, представленным в этом замечательном посте: http://blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html

Поэтому в вашем случае это:

 echo $xml->children('http://www.webex.com/schemas/2002/06/service/event')->sessionName; 

Вывод:

Узнать QB в минутах

Много работая с simplexml, я так и делаю.

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

 <entry> <title type="text">My test entry</title> <gd:when startTime="2017-02-26T02:00:00Z" endTime="2017-02-26T03:00:00Z"/> <gc:notes type="string">A type</gc:notes> </entry> 

Необходимо отправить true как второй параметр для функции children:

  $title = (string) $entry->title; $gd = $entry->children('gd', TRUE); $attrs = $gd->when->attributes(); $startTime = (string) $attrs->startTime; $gc = $entry->children('gc', TRUE); $notes = (string) $gc->notes(); 

Я могу ошибаться, но я не думаю, что XML с символом двоеточия, подобным SOAP, можно корректно проанализировать с помощью SimpleXMLElement .

Я уверен, что есть более элегантный способ сделать это, но я обычно читаю содержимое файла в переменной с помощью file_get_contents() затем заменяю и SimpleXMLElement двоеточия, а затем отправляю его в SimpleXMLElement .