Intereting Posts

Получение подмножества узлов XML с помощью PHP

Используя PHP, как мне получить весь поднабор узлов из XML-документа? Я могу получить что-то вроде:

<?xml version="1.0" encoding="utf-8"?> <people> <certain> <name>Jane Doe</name> <age>21</age> </certain> <certain> <certain> <name>John Smith</name> <age>34</age> </certain> </people> 

Но что, если я хочу только вернуть дочерние узлы?

  <certain> <name>Jane Doe</name> <age>21</age> </certain> <certain> <certain> <name>John Smith</name> <age>34</age> </certain> 

EDIT: Я пытаюсь получить подмножество XML и передать это прямо, а не объект, такой как simplexml, даст мне. Я в основном пытаюсь заставить PHP делать то, что делает OuterXml .NET … возвращает буквально вышеупомянутое подмножество XML, как … не интерпретирует или не конвертирует или не создает новый XML-файл или что-то еще … просто извлеките эти узлы на месте и передать их. Должен ли я получить файл XML, проанализировать, что мне нужно, а затем перестроить его как новый XML-файл? Если это так, мне нужно избавиться от <?xml version="1.0" encoding="utf-8"?> Bit … ugh.

Ответ будет заключаться в использовании XPath .

 $people = simplexml_load_string( '<?xml version="1.0" encoding="utf-8"?> <people> <certain> <name>Jane Doe</name> <age>21</age> </certain> <certain> <name>John Smith</name> <age>34</age> </certain> </people>' ); // get all <certain/> nodes $people->xpath('//certain'); // get all <certain/> nodes whose <name/> is "John Smith" print_r($people->xpath('//certain[name = "John Smith"]')); // get all <certain/> nodes whose <age/> child's value is greater than 21 print_r($people->xpath('//certain[age > 21]')); 

Возьмите 2

По-видимому, вы хотите скопировать некоторые узлы из документа в другой документ? SimpleXML этого не поддерживает. У DOM есть методы для этого, но они немного раздражают. Какой из них вы используете? Вот что я использую: SimpleDOM . Фактически, это действительно SimpleXML дополняется методами DOM.

 include 'SimpleDOM.php'; $results = simpledom_load_string('<results/>'); foreach ($people->xpath('//certain') as $certain) { $results->appendChild($certain); } конкретные include 'SimpleDOM.php'; $results = simpledom_load_string('<results/>'); foreach ($people->xpath('//certain') as $certain) { $results->appendChild($certain); } 

Эта процедура находит все узлы <certain/> через XPath, а затем добавляет их в новый документ.

Вы можете использовать DOMDocument.GetElementsByTagName или можете:

Использовать XPath?

 <?php $xml = simplexml_load_file("test.xml"); $result = $xml->xpath("//certain"); print_r($result); ?> 

Используйте DOM и XPath. Xpath позволяет вам выбирать узлы (и значения) из XML DOM.

 $dom = new DOMDocument(); $dom->loadXml($xml); $xpath = new DOMXpath($dom); $result = ''; foreach ($xpath->evaluate('/people/certain') as $node) { $result .= $dom->saveXml($node); } echo $result; 

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

DOMDocument :: saveXml () имеет аргумент контекста. Если при условии, что он сохраняет этот узел как XML. Очень похоже на outerXml() . PHP также может регистрировать собственные классы для узлов DOM. Таким образом, можно добавить функцию outerXML() в узлы элемента.

 class MyDomElement extends DOMElement { public function outerXml() { return $this->ownerDocument->saveXml($this); } } class MyDomDocument extends DOMDocument { public function __construct($version = '1.0', $encoding = 'utf-8') { parent::__construct($version, $encoding); $this->registerNodeClass('DOMElement', 'MyDomElement'); } } $dom = new MyDomDocument(); $dom->loadXml($xml); $xpath = new DOMXpath($dom); $result = ''; foreach ($xpath->evaluate('/people/certain') as $node) { $result .= $node->outerXml(); } echo $result; 

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

Ответ оказался комбинацией предложения xpath и вывода с помощью asXML() .

Используя пример Джоша Дэвиса:

 $people = simplexml_load_string( <?xml version="1.0" encoding="utf-8"?> <people> <certain> <name>Jane Doe</name> <age>21</age> </certain> <certain> <name>John Smith</name> <age>34</age> </certain> </people>' ); // get all <certain/> nodes $nodes = $people->xpath('/people/certain'); foreach ( $nodes as $node ) { $result .= $node->asXML()."\n"; } echo $result;