1

I'm using simplexml to read a xml file. So far i'm unable to get the attribute value i'm looking for. this is my code.

          if(file_exists($xmlfile)){
              $doc = new DOMDocument();
              $doc->load($xmlfile);
              $usergroup = $doc->getElementsByTagName( "preset" );
              foreach($usergroup as $group){         
                 $pname = $group->getElementsByTagName( "name" );
                 $att = 'code';
                 $name = $pname->attributes()->$att; //not working

                 $name = $pname->getAttribute('code'); //not working
                 if($name==$preset_name){
                     echo($name);
                      $group->parentNode->removeChild($group);
                 }
              }
          }

and my xml file looks like

<presets>
<preset>
 <name code="default">Default</name>
  <createdBy>named</createdBy>
  <icons>somethignhere</icons>
 </preset>
</presets>
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
guitarlass
  • 1,587
  • 7
  • 21
  • 45

2 Answers2

3

Try this :

function getByPattern($pattern, $source)
{
    $dom = new DOMDocument();
    @$dom->loadHTML($source);

    $xpath = new DOMXPath($dom);
    $result = $xpath->evaluate($pattern);

    return $result;
}

And you may use it like (using XPath) :

$data = getByPattern("/regions/testclass1/presets/preset",$xml);

UPDATE


Code :

<?php
    $xmlstr = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><presets><preset><name code=\"default\">Default</name><createdBy>named</createdBy><icons>somethignhere</icons></preset></presets>";

    $xml = new SimpleXMLElement($xmlstr);

    $result = $xml->xpath("/presets/preset/name");

    foreach($result[0]->attributes() as $a => $b) {
        echo $a,'="',$b,"\"\n";
    }

?>

Output :

code="default"

P.S. And also try accepting answers as @TJHeuvel mentioned; it's an indication that you respect the community (and the community will be more than happy to help you more, next time...)

Dr.Kameleon
  • 22,532
  • 20
  • 115
  • 223
  • thanks i dont understand how to get the attribute value from your code. And i have posted a wrong xml code please check the edit. – guitarlass Apr 27 '12 at 09:11
  • @guitarlass What is it that you don't understand? Just copy-paste the function I sent you, and use it as I've shown you (to get a specific element). if you want to get `/presets/preset/name` (= the full path to your element), then use it like `$data = getByPattern("/presets/preset/name",$xml)`. Simple as that. :-) – Dr.Kameleon Apr 27 '12 at 09:13
  • yes i undertand that but, how can i get the attribute `code` 's value ? – guitarlass Apr 27 '12 at 09:16
  • @guitarlass if you have the element stored in `$data`, then to get the `code` attribute, just try : `$data->getAttribute("code")`. – Dr.Kameleon Apr 27 '12 at 09:18
  • ok thanks but why doesn't my code working? i have coded `$name = $pname->getAttribute('code');` – guitarlass Apr 27 '12 at 09:22
  • @guitarlass IF `$pname` is what you think it is, then it SHOULD work. It's not working? Then `$pname` is most likely NOT what you think it is. Have checked the element is there? – Dr.Kameleon Apr 27 '12 at 09:25
  • even if i use your code i still get this error `Call to undefined method DOMNodeList::getAttribute() ` – guitarlass Apr 27 '12 at 09:27
  • @guitarlass OK, let's see. Is your xml file containing JUST what you posted in your question, or is there more to it? (if so, please repost ALL of it) – Dr.Kameleon Apr 27 '12 at 09:30
  • I have other blocks of with different values, inside . and contains a comma separated list. thats all.. – guitarlass Apr 27 '12 at 09:35
  • thanks so for this do i have to use get_file_contents($xml) to take it as a string? – guitarlass Apr 27 '12 at 10:08
  • @guitarlass if you want to directly load from a file path, try : `new SimpleXMLElement($filepath,0,true);` instead of `new SimpleXMLElement($xmlstr);`. :-) – Dr.Kameleon Apr 27 '12 at 10:14
  • yes its working thanks a lot. I hate working with file system. :( i have to include every data within xml. isn't there a easy way to execute these files? like predefined methods to delete a node, find a node .. etc ? – guitarlass Apr 27 '12 at 10:20
  • @guitarlass Glad to have helped! (For a complete reference on SimpleXMLElement, have a look at the documentation - there are lots of example there : http://php.net/manual/en/class.simplexmlelement.php). Also, please do accept the answer (it's a nice way for the community to see that it helped). – Dr.Kameleon Apr 27 '12 at 10:22
  • how can i delete the parent node using this ..? :) – guitarlass Apr 27 '12 at 10:36
  • @guitarlass What do you mean? Delete ALL `preset` nodes and their contents? - Have a look here : http://www.kavoir.com/2008/12/how-to-delete-remove-nodes-in-simplexml.html – Dr.Kameleon Apr 27 '12 at 10:39
  • no just the one that matches the attribute value im checking. thought of using`$result[0]->parentNode->parentNode->removeChild(?)` but how can i select relevant node in which exists? – guitarlass Apr 27 '12 at 10:44
  • @guitarlass See the link on my previous comment (I *think* using `unset` might work...) – Dr.Kameleon Apr 27 '12 at 10:44
  • unset($xml –> presets–>preset); will delete all the nodes? – guitarlass Apr 27 '12 at 10:49
  • @guitarlass Just specific a **particular** nod you want, and `unset` it. – Dr.Kameleon Apr 27 '12 at 10:51
  • ok, i gave it another thought , but i just dont know how to select the relevant node to delete after selecting $a which has the matching attribute value. i can get node which is `$result[0]` but how can i get the parent node of which is the relevant node? – guitarlass Apr 27 '12 at 11:03
  • @guitarlass just play with the xpath : `$result = $xml->xpath("/presets/preset");`. Btw, XPath is by far the easiest way to play with XML - for docs, have a look here : http://www.w3schools.com/xpath/xpath_syntax.asp – Dr.Kameleon Apr 27 '12 at 11:04
  • Please edit the relevant information into the question and/or answer, or even post new answers with new details if that is warranted. The comment section of a question/answer is only meant for relevant information regarding the actual post at hand, like mistakes, requests for more details, etc. not for long discussions even though they may be helpful to the people involved. If you need to continue this discussion, consider taking it to a chat room instead. – Lasse V. Karlsen Apr 27 '12 at 11:27
1

Actually question in my head includes deleting a node as well , mistakenly i could not add it. So in my point of view this is the complete answer, i a case if someone else find this useful. This answer doesn't include SimpleXMLElement class because how hard i tried it didn't delete the node with unset(); . So back to where i was , i finally found an answer. This is my code. and its Simple!!!

if(file_exists($xmlfile)){
              $doc = new DOMDocument();
              $doc->load($xmlfile);
              $presetgroup = $doc->getElementsByTagName( "preset" );
              foreach($presetgroup as $group){       
                 $pname = $group->getElementsByTagName( "name" );
                  $pcode = $pname->item(0)->getAttribute('code');
                 if($pcode==$preset_name){
                      echo($preset_name);
                      $group->parentNode->removeChild($group);
                 }
              }
          }
        $doc->save($xmlfile);
guitarlass
  • 1,587
  • 7
  • 21
  • 45