简体   繁体   中英

How can I print specific content of a child node with XPATH in PHP?

I have an XPATH query I am running in PHP against the following XML from CWE:

<Weaknesses>
<Weakness ID="211" Name="Test" Weakness_Abstraction="Base" Status="Incomplete">
<Description>
<Description_Summary>
The software performs an operation that triggers an external diagnostic or error message that is not directly generated by the software, such as an error generated by the programming language interpreter that the software uses. The error can contain sensitive system information.
</Description_Summary>
</Description>
</Weakness>
</Weaknesses>

I have written the following PHP with XPATH in order to target the content within the "Description_Summary" child node, however, it simply returns Array(). I have a $_GET which pulls the $searchString variable from the previous page, pointing to my specific attribute found within the "Weakness" node.

<?php
$searchString = $_GET["searchString"];
echo "<b>CWE Name: </b>" . $searchString . "</br>";
$xml = simplexml_load_file("cwe.xml");

$description = $xml->xpath('//Weakness[@Name="'. $searchString .'"]/Description/Description_Summary/text()');

echo "<pre>"; print_r($description); echo "</pre>";

?>

What it currently returns:

Array
(
    [0] => SimpleXMLElement Object
        (
        )

)

What is wrong with my print statement or XPATH query? Thanks!

Nothing is wrong with your code. With some modifications to read from a string, I tested this on codepad and it worked fine .

<?php
$xml = '<Weaknesses>
<Weakness ID="211" Name="Test" Weakness_Abstraction="Base" Status="Incomplete">
<Description>
<Description_Summary>
The software performs an operation that triggers an external diagnostic or error message that is not directly generated by the software, such as an error generated by the programming language interpreter that the software uses. The error can contain sensitive system information.
</Description_Summary>
</Description>
</Weakness>
</Weaknesses>';

$searchString = 'Test';
echo "<b>CWE Name: </b>" . $searchString . "</br>";
$xml = simplexml_load_string($xml);

$description = $xml->xpath('//Weakness[@Name="'. $searchString .'"]/Description/Description_Summary/text()');

echo "<pre>"; print_r((string) $description[0]); echo "</pre>";

?>

And returns this:

<b>CWE Name: </b>Test</br><pre>
The software performs an operation that triggers an external diagnostic or error message that is not directly generated by the software, such as an error generated by the programming language interpreter that the software uses. The error can contain sensitive system information.
</pre>

It is probably the case that the file doesn't contain what you think it does, or the $searchString isn't equal to Test .

What is wrong with my print statement.

Looks not too-wrong but has some problems. First you could reduce it to a single expression perhaps:

echo "<pre>", print_r($description, true), "</pre>";

but this is merely cosmetic. The other thing that looks wrong is that you're using print_r on a SimpleXMLElement . Both print_r and var_dump do not work well with simplexml because of the magic those objects have.

Instead just echo them out as XML, this should be most descriptive:

echo "<pre>", htmlspecialchars($description[0]->asXML()), "</pre>";

Exemplary output (plain text):

<pre>&lt;Description_Summary&gt;
The software performs an operation that triggers an external diagnostic or error message that is not directly generated by the software, such as an error generated by the programming language interpreter that the software uses. The error can contain sensitive system information.
&lt;/Description_Summary&gt;</pre>

This already shows that you didn't query any text-nodes here but an element. Read on why.

What's wrong with my XPath query?

You are using the simplexml extenstion. It has limited xpath support by what it can return. As your example shows, invoking the xpath() method does not fail, however, in the return array, there are no text-nodes because a SimpleXMLElement can not be a text-node .

Therefore having an XPath expression that queries for text-nodes like you did ( ... text() ) is kinda wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM