Jump to content

Warning: DOMXPath::evaluate(): Invalid expression


oach

Recommended Posts

Hello All,

 

I have searched these forums and the net but haven't found an exact answer.  I have a "path" (could be paths) that is/are causing warnings as it/they is/are poorly formed.  This is bloating our logs, therefore I need to alleviate the issue.

There are thousands of paths in the database so I do not know which are causing issues.

I know I can add the "@" to the call to quiet the warning.  First question: does that keep the warning from going into the logs?

 

I would prefer not to use the method above as it bypasses the real issue. 

Looking at the SimpleXMLElement documentation along with DOMDocument and DOMXPAth, I can't find a way to validate the actual path.  All of the below throw a warning or notice:

$xpath->evaluate($path);
$xpath->query($path);
$node->xpath($path);

Final question: Is there a "simple" way to validate the $path prior to actually making the call to one of the methods of the various XML PHP classes?

 

Thank you for your time and assistance.

Edited by oach
Link to comment
Share on other sites

There are back-to-back warnings on the $node->xpath($path) call.

  • Warning: SimpleXMLElement::xpath(): Invalid expression in /var/www/html/test/xml.php on line...
  • arning: SimpleXMLElement::xpath(): xmlXPathEval: evaluation failed in /var/www/html/test/xml.php on line...

The test file is trying to mimic what is happening in production in an easy to reproduce situation.

Link to comment
Share on other sites

The functions you list all say they return false on an error such as a bad path, so check for that and log the details you need to determine which path is invalid so you can fix it.

$result = $xpath->evaluate($path);
if ($result === false){
    trigger_error('Invalid XPath: '.$path, E_USER_WARNING);
}

If you want to prevent the built-in warning, then use libxml_use_internal_errors.

libxml_use_internal_errors(true);
$result = $xpath->evaluate($path);
if ($result === false){
    $errors = libxml_get_errors();
    $errors = array_reduce($errors, function($carry, $error){
        return sprintf("%s[%s:%d] %s\r\n", $carry, $error->file, $error->line, $error->message);
    }, '');
    trigger_error(sprintf("Invalid XPath: %s\r\nErrors: %s", $path, $errors), E_USER_WARNING);
}
libxml_use_internal_errors(false);

 

Link to comment
Share on other sites

4 hours ago, oach said:

I know I can add the "@" to the call to quiet the warning.  First question: does that keep the warning from going into the logs?

Depends on your setup. With normal PHP yes, silencing the error keeps it suppressed.
If you have a logging system set up to intercept and log errors then it depends. PHP will invoke the system's custom error logger even with @s, but in such a way that smart code will be able to recognize that happened and not log it. A naive logger will see "omg error, gotta log it".

For the record. You're right in that you shouldn't do it: hiding errors doesn't make them go away, just like how stopping Covid-19 testing doesn't mean there are no more cases.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.