Используя 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]'));
По-видимому, вы хотите скопировать некоторые узлы из документа в другой документ? 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;