Jared
Jared

Reputation: 1264

PHP SimpleXML with XPath

I have an XML structure that looks like this:

<?xml version="1.0"?>
<survey>
  <responses>0</responses>
  <question>
    <title>Some survey question</title>
    <answer>
      <title>Answer 1</title>
      <responses>0</responses>
    </answer>
    <answer>
      <title>Answer 2</title>
      <responses>0</responses>
    </answer>
    ...
  </question>
  ...
</survey>

I want to increment the <responses> values for answers that match the values in a $response array. Here's how the $response array is structured:

$response = array(
  'sid' => session_id(),
  'answers' => array(
    $_POST['input1'],
    $_POST['input2'],
    ...
  )
);

I have a SimpleXMLElement called $results for my survey xml file. Here's how I'm going about it:

$results = simplexml_load_file($surveyResultsFile);

$i = 1;
foreach($response->answers as $answer) {
  $r = $results->xpath("question[$i]/answer[title='$answer']/responses");
  $r = $r[0];
  $r = intval($r) + 1;
  $i++;
}

file_put_contents($surveyResultsFile, $results->asXML());

My results aren't being saved after incrementing the value of $r. Any ideas on what I'm doing wrong? Thanks!

Upvotes: 2

Views: 2808

Answers (2)

Josh Davis
Josh Davis

Reputation: 28730

There are several errors in your script, which explains why it doesn't work. First, your $response array doesn't seem right. Did you really intend to use variables in place of keys? Try print_r($response); and see if it's really what you want.

You can select the nth <question/> using the array notation (0-based) as in

$results->question[$i]

Once you get the right question, all you need to do is verify that it does indeed contain the suggested answer with XPath. Then only, you can increment the value of <responses/>. Also, you have to escape special characters such as < or ", which would make your XPath query fail.

Finally, you can use asXML() to actually save the file (no file_put_contents() needed here.) I assume that your $surveyResults is a typo and that you meant $surveyResultsFile.

$response = array(
    'sid'     => session_id(),
    'answers' => array(
        $_POST['input1']
    )
);

$results = simplexml_load_file($surveyResultsFile);

foreach ($response['answers'] as $i => $answer) {
    $title = htmlspecialchars($answer);
    $a = $results->question[$i]->xpath('answer[title="' . $title . '"]');

    if (empty($a))
    {
        echo "No answer '$title' for question $i\n";
        continue;
    }
    ++$a[0]->responses;
}

$results->asXML($surveyResultsFile);

Upvotes: 2

TuomasR
TuomasR

Reputation: 2316

One problem might be this:

$r = $results->xpath('/question[$i]/answer[title=$answer]/responses');

Since you're using single quotes (the ' -character, is the actual English name "single quote"?), the variables in the XPath experssion aren't being evaluated, instead it's processed literally. Replace the single quotes with normal quotes (") and the variables will be processed normally.

See: http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.single

Upvotes: 0

Related Questions