0

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!

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
user1995565
  • 165
  • 1
  • 10
  • is this a typo: `Description/Description_Text/text()`? Did you mean to use `Description/Description_Summary/text()`? – Joe Jul 16 '13 at 02:28
  • Yes, thank you Joe, it is a typo. I will correct that. – user1995565 Jul 16 '13 at 02:43
  • your xpath query looks fine, are you sure yout $searchString is 'Test'. – Desu Jul 16 '13 at 03:05
  • I am certain, as when I remove /Description_Summary/text() it returns the sub nodes and content found within Description. Am I printing out the array incorrectly? – user1995565 Jul 16 '13 at 03:12

2 Answers2

0

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.

  • Interesting, I see. Well, let me paste a full example of a Weakness stanza in pastebin and maybe you can tell me if I am missing something. Found here: http://pastebin.com/pKZpw3qQ As a side-question, if I wanted to print only the string found within SimpleXMLElement Object, how would I go about that? – user1995565 Jul 16 '13 at 03:36
  • The second bit is easy, just cast the Object to a string. I can edit that into the answer. –  Jul 16 '13 at 03:42
  • The former: With the right argument to the XPath still seems to work - http://codepad.org/YlZRQDok Is there a chance an incorrect `$searchString` is being given? –  Jul 16 '13 at 03:45
  • There must be something simple that I am messing up on as I have been hardcoding the string "Test" for both the attribute as well as placing it within the XPath query. I guess I will have to take another look as you have already proven yourself correct many times! Thanks again, though! – user1995565 Jul 16 '13 at 03:54
  • Apparently the way I was loading the XML file was incorrect? Once I changed it to the full path with the file instead of simply the filename, it started working! Weird, eh? Thanks for your help! – user1995565 Jul 16 '13 at 04:00
0

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.

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836