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
Повеселись.