XML-синтаксический анализ, но имена элементов – динамические

Simple XMLElement Object ( [IpStatus] => 1 [ti_pid_20642] => SimpleXmlElement Object ( 

У меня есть SimpleXMLElment в вышеуказанном формате, и этот XML генерируется во время выполнения, и его значения узлов, такие как ti_pid_20642 , частично dnymaic, например ti_pid_3232 , ti-pid_2323 , ti_pid_anyumber .

Мой вопрос: как я могу получить эти значения узлов, а дети – с помощью PHP?

Чтобы получить все имена узлов, которые используются в XML- строке с SimpleXML, вы можете использовать SimpleXMLIterator :

 $tagnames = array_keys(iterator_to_array( new RecursiveIteratorIterator( new SimpleXMLIterator($string) , RecursiveIteratorIterator::SELF_FIRST ) )); print_r($tagnames); 

Что могло бы дать вам пример (вы не дали никакого XML в своем вопросе, Demo ):

 Array ( [0] => IpStatus [1] => ti_pid_20642 [2] => dependend [3] => ti-pid_2323 [4] => ti_pid_anyumber [5] => more ) 

Если у вас возникли проблемы с предоставлением строки, содержащей действительный XML, возьмите свой существующий SimpleXMLelement и создайте из него строку XML :

 $string = $simpleXML->asXML(); 

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

 class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator { private $element; public function __construct(SimpleXMLElement $element) { parent::__construct($element); } public function hasChildren() { return (bool)$this->current()->children(); } public function getChildren() { return new self($this->current()->children()); } } 

Его использование будет аналогичным ( Demo ):

 $it = new RecursiveIteratorIterator( new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST ); $tagnames = array_keys(iterator_to_array($it)); 

Это зависит от того, что вам нужно.

Это становится менее прямым, с именами элементов. В зависимости от того, хотите ли вы получить только локальные имена или имена пространства имен или даже URI пространства имен с тэгами.

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

 /** * SimpleXMLElementIterator over all child elements across namespaces */ class SimpleXMLElementIterator extends IteratorIterator implements RecursiveIterator { private $element; public function __construct(SimpleXMLElement $element) { parent::__construct(new ArrayIterator($element->xpath('./*'))); } public function key() { return $this->current()->getName(); } public function hasChildren() { return (bool)$this->current()->xpath('./*'); } public function getChildren() { return new self($this->current()); } } 

Затем вам нужно будет проверить пространство имен для каждого элемента. В качестве примера используется модифицированный XML-документ с использованием пространств имен:

 <root xmlns="namspace:default" xmlns:ns1="namespace.numbered.1"> <ns1:IpStatus>1</ns1:IpStatus> <ti_pid_20642> <dependend xmlns="namspace:depending"> <ti-pid_2323>ti-pid_2323</ti-pid_2323> <ti_pid_anyumber>ti_pid_anyumber</ti_pid_anyumber> <more xmlns:ns2="namspace.numbered.2"> <ti_pid_20642 ns2:attribute="test">ti_pid_20642</ti_pid_20642> <ns2:ti_pid_20642>ti_pid_20642</ns2:ti_pid_20642> </more> </dependend> </ti_pid_20642> </root> 

В сочетании с обновлением SimpleXMLIterator выше следующего примера-кода демонстрируется новое поведение:

 $xml = new SimpleXMLElement($string); $it = new RecursiveIteratorIterator( new SimpleXMLElementIterator($xml), RecursiveIteratorIterator::SELF_FIRST ); $count = 0; foreach ($it as $name => $element) { $nsList = $element->getNamespaces(); list($ns, $nsUri) = each($nsList); printf("#%d: %' -20s %' -4s %s\n", ++$count, $name, $ns, $nsUri); } 

Выход ( демо ):

 #1: IpStatus ns1 namespace.numbered.1 #2: ti_pid_20642 namspace:default #3: dependend namspace:depending #4: ti-pid_2323 namspace:depending #5: ti_pid_anyumber namspace:depending #6: more namspace:depending #7: ti_pid_20642 namspace:depending #8: ti_pid_20642 ns2 namspace.numbered.2 

Повеселись.