Mac Taylor
Mac Taylor

Reputation: 5148

Get elements from a XML content by PHP

I am trying to get elements from this XML content but returns empty:

<results>
  <error>
    <string>i</string>
    <description>Make I uppercase</description>
    <precontext></precontext>
    <suggestions>
        <option>I</option>
    </suggestions>
    <type>grammar</type>    
  </error>
</results>

And this is my code to extract element type of grammar :

$dom = new DOMDocument();
$dom->loadXml($output);
$params = $dom->getElementsByTagName('error'); // Find Sections
$k=0;
foreach ($params as $param) //go to each section 1 by 1
{
    if($param->type == "grammar"){
        echo $param->description;
    }else{
        echo "other type";
    }

Problem is the script returns empty.

Upvotes: 0

Views: 83

Answers (4)

ThW
ThW

Reputation: 19482

You're mixing DOM with SimpleXML. This is possible, but you would need to convert the DOM element node into a SimpleXML instance with simplexml_import_dom().

Or you use Xpath. getElementsByTagName() is a low level DOM method. Using Xpath expressions allows for more specific access with a lot less code.

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('//error') as $error) {
    var_dump(
        [
            'type' => $xpath->evaluate('string(type)', $error),
            'description' => $xpath->evaluate('string(description)', $error)
        ]
    );
}

Output:

array(2) {
  ["type"]=>
  string(7) "grammar"
  ["description"]=>
  string(16) "Make I uppercase"
}

Xpath expressions allow for conditions as well, for example you could fetch all grammar errors using //error[@type = "grammar"].

Upvotes: 1

Array
Array

Reputation: 21

I think is this what you want.

       <?php

    $output  = '<results>
      <error>
        <string>i</string>
        <description>Make I uppercase</description>
        <precontext></precontext>
        <suggestions>
            <option>I</option>
        </suggestions>
        <type>grammar</type>    
      </error>
    </results>';

    $dom = new DOMDocument();
    $dom->loadXml($output);
    $params = $dom->getElementsByTagName('error'); // Find Sections
    $k=0;


    foreach ($params as $param) //go to each section 1 by 1
    {
        $string = $param->getElementsByTagName( "string" )->item(0)->nodeValue;
        $description = $param->getElementsByTagName( "description" )->item(0)->nodeValue;
        $option = $param->getElementsByTagName( "option" )->item(0)->nodeValue;
        $type = $param->getElementsByTagName( "type" )->item(0)->nodeValue;
        echo $type;
        if($type == "grammar"){
            echo $description ;
        }else{
            echo "other type";
        }
    }
?>

Upvotes: 1

&#193;lvaro Gonz&#225;lez
&#193;lvaro Gonz&#225;lez

Reputation: 146380

You apparently haven't configured PHP to report errors because your code triggers:

Notice: Undefined property: DOMElement::$type

You need to grab <type> the same way you grab <error>, using DOM methods like e.g. getElementsByTagName(). Same for node value:

if ($param->getElementsByTagName('type')->length && $param->getElementsByTagName('type')[0]->nodeValue === 'grammar') {
    // Feel free to add additional checks here:
    echo $param->getElementsByTagName('description')[0]->nodeValue;
}else{
    echo "other type";
}

Demo

Upvotes: 1

Devsi Odedra
Devsi Odedra

Reputation: 5322

you can use simplexml_load_string()

 $output = '<results>
      <error>
        <string>i</string>
        <description>Make I uppercase</description>
        <precontext></precontext>
        <suggestions>
            <option>I</option>
        </suggestions>
        <type>grammar</type>    
      </error>
    </results>';


    $xml = simplexml_load_string($output);

    foreach($xml->error as $item)
    {
        //echo (string)$item->type;

        if($item->type == "grammar"){

        echo $item->description;

        }else{
         echo "other type";

        }
    }

Upvotes: 1

Related Questions