0

I've the following 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>

I need to get the ShortMessage for the given ItemID that is found in ErrorParameters/Value where ParamID="ItemID"

I've been able to check if a node with the given value exists:

$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;

then I tried to get its ShortMessage with

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

but got invalid predicate as expected since not find the right way to combine filters.

can pls suggest the right way?

Thanks

2 Answers 2

2

Here are several ways

  1. Select the Errors element node using nested conditions:
    //e:Errors[e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]]/e:ShortMessage
  2. Select the Value element and use the parent axis
    //e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/parent::*/parent::*/e:ShortMessage
  3. Select the Value element and use the ancestor axis
    //e:ErrorParameters[@ParamID="ItemID"]/e:Value[. = "770386906435"]/ancestor::e:Errors/e:ShortMessage

If you use DOMXpath::evaluate() you can use count() and string() to fetch the scalar values directly. You might not even need to check if the node exists, because the result will be an empty string in this case.

$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);

Output:

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."
Sign up to request clarification or add additional context in comments.

Comments

1

If you use the XPath to fetch the short message, a quick way to check if there is a message is to just check if there are any results from the query...

$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";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.