PHP 7.2 xml domdocument получает значение узла для заданного значения дочернего узла родного брата, имеющего атрибут, равный - PullRequest
0 голосов
/ 02 января 2019

У меня есть следующий xml

<ReviseInventoryStatusResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2019-01-02T15:42:31.495Z</Timestamp>
  <Ack>Warning</Ack>
  <Errors>
    <ShortMessage>Requested StartPrice and Quantity revision is redundant.</ShortMessage>
    <LongMessage>The existing price and quantity values are identical to those specified in the request and, therefore, have not been modified.</LongMessage>
    <ErrorCode>21917091</ErrorCode>
    <SeverityCode>Warning</SeverityCode>
    <ErrorParameters ParamID="ItemID">
      <Value>770386906435</Value>
    </ErrorParameters>
    <ErrorParameters ParamID="SKU">
      <Value/>
    </ErrorParameters>
    <ErrorClassification>RequestError</ErrorClassification>
  </Errors>
  <Errors>
    <ShortMessage>Requested StartPrice and Quantity revision is redundant.</ShortMessage>
    <LongMessage>The existing price and quantity values are identical to those specified in the request and, therefore, have not been modified.</LongMessage>
    <ErrorCode>21917091</ErrorCode>
    <SeverityCode>Warning</SeverityCode>
    <ErrorParameters ParamID="ItemID">
      <Value>770386906436</Value>
    </ErrorParameters>
    <ErrorParameters ParamID="SKU">
      <Value/>
    </ErrorParameters>
    <ErrorClassification>RequestError</ErrorClassification>
  </Errors>
  ...
  </ReviseInventoryStatusResponse>

Мне нужно получить ShortMessage для данного ItemID, который находится в ErrorParameters / Value, где ParamID = "ItemID"

был в состоянии проверить, существует ли узел с данным значением:

$xmlr = new DOMDocument();
$xmlr->load('ReviseInventoryStatusResponse_error.xml');
$xpath = new DOMXPath($xmlr);
$xpath->registerNamespace('e', 'urn:ebay:apis:eBLBaseComponents');
$nodeExists=($xpath->query('//e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]')->length>0)?1:0;

, тогда я попытался получить его ShortMessage с

$xpath->query('//e:Errors[e:ErrorParameters@ParamID="ItemID"]/e:Value[.="770386906435"]/e:ShortMessage')

, но получил неверный предикат, как и ожидалось, так как не нашел нужногоспособ объединить фильтры.

может предложить, пожалуйста, правильный путь?

Спасибо

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Если вы используете XPath для извлечения короткого сообщения, быстрый способ проверить, есть ли сообщение, - это просто проверить, есть ли какие-либо результаты запроса ...

$smgs = $xpath->query('//e:Errors[e:ErrorParameters[@ParamID="ItemID" and e:Value="7720386906435"]]/e:ShortMessage');
if ( count($smgs) > 0 ) {
    echo $smgs[0]->nodeValue;
}
else {
    echo "does not exist";
}
0 голосов
/ 02 января 2019

Вот несколько способов

  1. Выберите узел элемента Errors, используя вложенные условия:
    //e:Errors[e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]]/e:ShortMessage
  2. Выберите элемент Value и используйте parent axis
    //e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/parent::*/parent::*/e:ShortMessage
  3. Выберите элемент Value и используйте ancestor axis
    //e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/ancestor::e:Errors/e:ShortMessage

Если вы используете DOMXpath::evaluate(), вы можетеиспользуйте count() и string() для непосредственного извлечения скалярных значений.Возможно, вам даже не понадобится проверять, существует ли узел, потому что в этом случае результатом будет пустая строка.

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXPath($document);
$xpath->registerNamespace('e', 'urn:ebay:apis:eBLBaseComponents');
$nodeExists = $xpath->evaluate(
  'count(//e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]) > 0'
);

var_dump($nodeExists);

$shortMessage = $xpath->evaluate(
  'string(//e:Errors[e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]]/e:ShortMessage)'
);
var_dump($shortMessage);

$shortMessage = $xpath->evaluate(
  'string(//e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/parent::*/parent::*/e:ShortMessage)'
);
var_dump($shortMessage);

$shortMessage = $xpath->evaluate(
  'string(//e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/ancestor::e:Errors/e:ShortMessage)'
);
var_dump($shortMessage);

Вывод:

bool(true) 
string(56) "Requested StartPrice and Quantity revision is redundant." 
string(56) "Requested StartPrice and Quantity revision is redundant." 
string(56) "Requested StartPrice and Quantity revision is redundant."
...