Извлечь данные из нескольких строк XML

У меня действительно странный XML-ответ, и мне нужно извлечь его данные. Мне нужно получить данные в атрибуте «value», но мне нужно выбрать их в соответствии с их атрибутами «key».

Вот так это выглядит

       <phone>
2125556666
</phone>
<State>
ny
</State>
<Response>
<data key="Supported" value="Yes"/>
<data key="Host" value="Remote"/>
<data key="WholeProductList">
<data key="Product" value="a-z44"/>
<data key="Product" value="c-k99"/>
<data key="Product" value="e-b089"/>
<data key="Product" value="z-p00"/>
<data key="Product" value="r-333"/>
<data key="Product" value="t-RS232"/>
<data key="Product" value="4-lve"/>
<data key="Product" value="Shutdown"/>
</data>
</Response>

В PHP у меня есть

$xmltmp = new DomDocument;
$xmltmp->loadXml($response);
$phone = $xmlresponse->getElementsByTagName('phone')->item(0)->nodeValue;
$state = $xmlresponse->getElementsByTagName('state')->item(0)->nodeValue;
echo $phone;
echo $state;

В настоящее время выводит как номер телефона, так и состояние. Работает нормально.

Теперь мне нужно знать, является ли значение «Поддерживаемого» ключа Да или Нет, и если да, мне нужно получить все «Продукты». Я немного застрял, потому что мне трудно сделать оператор foreach и затем проверить значение атрибута «ключ».

Спасибо!

1

Решение

Ваш XML неверен. XML-документ всегда нуждается в одном узле элемента документа.

Пример:

<root>
<phone>2125556666</phone>
<State>ny</State>
<Response>
<data key="Supported" value="Yes"/>
...
</data>
</Response>
</root>

Самый простой способ извлечь данные из DOM — это XPath. В PHP это обеспечивается DOMXPath класс и часть ext/dom, DOMXPath::evaluate() позволяет извлекать списки узлов или скалярные значения из документа DOM.

$dom = new DOMDocument;
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);

$phone = $xpath->evaluate('string(/*/phone)');
$state = $xpath->evaluate('string(/*/State)');
var_dump($phone, $state);

Выход:

string(10) "2125556666"string(2) "ny"

Выражение как /*/phone выбирает все phone дочерние узлы элемента внутри элемента документа. string(/*/phone) бросает первый найденный узел в строку и возвращает его. Если узел не найден, он вернет пустую строку.

Выражение XPath для поддерживаемого статуса немного сложнее. Условия для узлов приведены в [], Можно сравнить результат непосредственно в XPath. Возвращаемое значение будет логическим.

$supported = $xpath->evaluate('/*/Response/data[@key="Supported"]/@value = "Yes"');
var_dump($supported);

Выход:

bool(true)

Если выражение возвращает список узлов, вы можете повторить его foreach(),

$nodes = $xpath->evaluate(
'/*/Response/data[@key="WholeProductList"]/data[@key="Product"]/@value'
);
$products = [];
foreach ($nodes as $attributeNode) {
$products[] = $attributeNode->value;
}
var_dump($products);

Выход:

array(8) {
[0]=>
string(5) "a-z44"[1]=>
string(5) "c-k99"[2]=>
string(6) "e-b089"[3]=>
string(5) "z-p00"[4]=>
string(5) "r-333"[5]=>
string(7) "t-RS232"[6]=>
string(5) "4-lve"[7]=>
string(8) "Shutdown"}
3

Другие решения

Это не будет работать «как есть», так как я не знаю, какова реальная структура документа XML, но вкратце вы отображаете узлы XML в XPath, как //root/node/child_node/@attribute и так далее.

Он также должен иметь некоторый здравый (не нулевой) тип проверки.

$xmltmp = new DomDocument;
$xmltmp->loadXml($response);
$xQuery = new DOMXPath($xmltmp);

//not sure what your root node is so the query path is probably wrong
$supported = $xQuery->query('/Response/data[@key="Supported"]/@value')->value;

Вы также можете заменить:

$phone = $xmlresponse->getElementsByTagName('phone')->item(0)->nodeValue;
$state = $xmlresponse->getElementsByTagName('state')->item(0)->nodeValue;

С чем-то вроде (опять же — без полной структуры XML-документа сам путь, вероятно, не совсем правильный):

$phone = $xQuery->query('/phone')->item(0)->nodeValue;
$state = $xQuery->query('/State')->item(0)->nodeValue;
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector