PHP xPath разбор SOAP

99
10

PHP xPath разбор SOAP

У меня есть запрос SOAP, который имеет тело, подобное приведенному ниже. (Я удалил нерелевантные узлы). Я просто хочу разобрать запрос для узлов NumInfo, которые имеют NumType HI. Мне нужно получить значения Type, Num, Desc, Quantity и PriceInfo для узлов с узлом NumInfo с NumType = HI.

Используя xpath, чтобы получить такие узлы:

$xml = simplexml_load_file('RequestExample.xml');
$xml->registerXPathNamespace("bms", "http://www.cieca.com/BMS");
$xml->xpath("//bms:Selected[contains(., 'HI')]")

будет получать выбранные узлы (узлы), содержащие HI. xpath возвращает массив объектов SimpleXML, правильно?

Как получить другую информацию для родителя, соответствующую этому узлу NumInfo? Кроме того, зарегистрировав пространство имен, не должен ли я опускать их в своих запросах на xpath?

<soap:Body>
<bms:ProcurementAddRq>
<bms:ProcurementFolder>
<bms:ProcurementInfo>
<bms:ProcurementList>
<bms:Procurement>
<bms:Selected>
<bms:NumInfo>
<bms:NumType>OE</bms:NumType>
<bms:Num>04715SNAA90ZZ</bms:Num>
</bms:NumInfo>
<bms:NumInfo>
<bms:NumType>HI</bms:NumType>
<bms:Num>187-01436</bms:Num>
</bms:NumInfo>
<bms:NumInfo>
<bms:NumType>HPT</bms:NumType>
<bms:Num>187</bms:Num>
</bms:NumInfo>
<bms:Type>PAN</bms:Type>
<bms:Desc>Cover</bms:Desc>
<bms:Quantity>1</bms:Quantity>
<bms:PriceInfo>
<bms:UnitListPrice>328.42</bms:UnitListPrice>
<bms:UnitNetPrice>328.42</bms:UnitNetPrice>
</bms:PriceInfo>
</bms:Selected>
</bms:Procurement>
<bms:Procurement>
<bms:Selected>
<bms:NumInfo>
<bms:NumType>OE</bms:NumType>
<bms:Num>71570SNAA00</bms:Num>
</bms:NumInfo>
<bms:Type>PAN</bms:Type>
<bms:Desc>Abs</bms:Desc>
<bms:Quantity>1</bms:Quantity>
<bms:PriceInfo>
<bms:UnitListPrice>49.80</bms:UnitListPrice>
<bms:UnitNetPrice>49.80</bms:UnitNetPrice>
</bms:PriceInfo>
</bms:Selected>
</bms:Procurement>
<bms:Procurement>
<bms:Selected>
<bms:NumInfo>
<bms:NumType>OE</bms:NumType>
<bms:Num>66100SNEA00ZZ</bms:Num>
</bms:NumInfo>
<bms:Type>PAN</bms:Type>
<bms:Desc>Panel</bms:Desc>
<bms:Quantity>1</bms:Quantity>
<bms:PriceInfo>
<bms:UnitListPrice>355.83</bms:UnitListPrice>
<bms:UnitNetPrice>355.83</bms:UnitNetPrice>
</bms:PriceInfo>
</bms:Selected>
<bms:Procurement>
<bms:Selected>
<bms:NumInfo>
<bms:NumType>OE</bms:NumType>
<bms:Num>04655SNE305ZZ</bms:Num>
</bms:NumInfo>
<bms:Type>PAP</bms:Type>
<bms:Desc>Pan</bms:Desc>
<bms:Quantity>1</bms:Quantity>
<bms:PriceInfo>
<bms:UnitListPrice>994.13</bms:UnitListPrice>
<bms:UnitNetPrice>994.13</bms:UnitNetPrice>
</bms:PriceInfo>
</bms:Selected>
</bms:ProcurementList>
</bms:ProcurementInfo>
</bms:ProcurementFolder>
</bms:ProcurementAddRq>
</soap:Body>

спросил(а) 2021-01-27T23:41:53+03:00 4 месяца, 4 недели назад
1
Решение
63

Вы должны иметь возможность получать данные с помощью...

$selected = $xml->xpath("//bms:Selected[bms:NumInfo/bms:NumType='HI']")[0];
echo (string)$selected->children("bms",true)->Desc;

Обратите внимание на [0] в конце функции XPath, это так, как вы говорите, потому что он возвращает список узлов, которые соответствуют. Обычно вы использовали бы это в foreach() но если есть только один, то вы можете сократить его таким образом.

Когда вы извлекаете узел, это на самом деле SimpleXMLElement, используя (string) выдает значение в строку, позволяя вам более гибко использовать его в качестве значения (echo делает это в любом случае, но это просто для того, чтобы показать принцип)

->children("bms",true) возвращают все дочерние узлы в пространстве имен (с использованием префикса), и это позволяет использовать ->Desc без префикса.

Даже если вы зарегистрируете пространство имен, вам все равно нужно использовать его в своих операторах XPath, это позволяет смешивать пространства имен и элементы. У вас может быть один и тот же элемент, но другое пространство имен, поэтому это означает, что вы ссылаетесь на правильный.

ответил(а) 2021-01-27T23:41:53+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема