Click here to Skip to main content
15,889,863 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
can someone explain to me, why an xpath expression as this:

PHP
/*Never mind the nodeObj, its been successfully instantiated with root node added internally*/

    $PageName = 'Home';
    $nodeObj->xpath("./*[name() = (following-sibling::$PageName | preceding-sibling::$PageName)/menu/*]/menu");


will return just one array of menu item like:

PHP
'menu' => 
    array (size=1)
      'item' => 
        array (size=3)
          0 => string 'Business Help' (length=13)
          1 => string 'Web Help' (length=8)
          2 => string 'Tour Help' (length=9)


instead of an array of two menu items like:

PHP
'menu' => 
    array (size=2)
      'item' => 
        array (size=3)
          0 => string 'Business Help' (length=13)
          1 => string 'Web Help' (length=8)
          2 => string 'Tour Help' (length=9)

      'item' => 
        array (size=2)
          0 => string 'About us' (length=8)
          1 => string 'About our food' (length=14)


Here is an extract of the xml stucture:

HTML
<Pages>          <!--This is the root node-->

    <Home>
        <url>...</url>
        <menu>
            <item>Help</item>
            <item>About</item>
            <item>Contact</item>
        </menu>
    </Home>

    <Help>   
          <url>...</url>            
          <menu>                           <!--i need to select this if its parent(Help) is listed in Home/menu/item above-->
            <item>Business Help</item>
            <item>Web Help</item>
            <item>Tour Help</item>
          </menu>
    </Help> 

    <About>  
          <url>...</url>          
          <menu>                          <!--And Or select this if its parent(About) is listed in Home/menu/item above-->
            <item>About us</item>
            <item>About our food</item> 
        </menu>
    </About>

    <Contact>                              
          <url>...</url>
          <menu>                          <!--And Or select this if its listed in Home/menu/item above-->
          ...                       
             and so on...
          ...
          </menu>
    </Contact>

</Pages>


and here's a snippet of the php code that attempts to maniplate it

PHP
/*
Here's a snippet of the class from from
which $nodeObj was stencilled :

class XMLManager {

    public static $xmlObj = null;                            //internal object 
    
    public $Err = array();                                  //Error code  
    
    public function __construct($rootName, $InitVersion = false, $PathToFile = '') {
                
        if(!$this->Create( $rootName, $InitVersion, $PathToFile )) 
                throw new XMLException($this->Err);     //Create sets $this->Err on failure 
                
    }

    //now, here's method Create()
    private function Create( $modelName, $VersionInit, $PathToFile = '') {   
                
        //turn off compatibility mode cause simple xml throws a wobbly if you don't.		
        if ( ini_get('zend.ze1_compatibility_mode') == 1 ){		
            ini_set ('zend.ze1_compatibility_mode', 0);		
        }
        
        libxml_use_internal_errors(true);
        
        if($this->getDOMObj($VersionInit, $PathToFile)) {
            return self::CreateRootNode(self::$xmlObj, $modelName);        basically calls on DOMDocument::createElement to add root (Pages in this case) to my dom.
        }
                
        return false;
    }

    public function getDOMObj($VersionInit = false, $PathToFile = ''){
        
        if(empty(self::$xmlObj)){
            self::$xmlObj = ($VersionInit == false) ?  new DOMDocument :  new DOMDocument('1.0', 'UTF-8');
            
            if(self::$xmlObj == null){
                $this->parseError();             //this parses internal xml error and assigns outcome to $this->Err
                return false;
            } 
            
            return (isset($PathToFile)) ? $this->Load(self::$xmlObj, $PathToFile) : true;
        }
        
        //echo 'success ';
        return  self::$xmlObj;
    }
}

usage:
so, when i created $nodeObj like this:
$nodeObj = new XMLManager('Pages', false, 'myPages.xml');

what i got was actually Pages (root node)     //that just what i liked 

supposedly,
$nodeObj->xpath("./*[...]");  //as above 
should select from current root node (Pages);

Note that xpath() is a custom method in XMLManager that returns feched result 
as array. mind you, it only returns what has been fetched by xpath in array 
form.
*/


What am i doing wrongly ? any help will be greatly appreciated.
Posted
Updated 27-Aug-15 7:59am
v2
Comments
PIEBALDconsult 27-Aug-15 14:16pm    
I expect it's because "(following-sibling::$PageName | preceding-sibling::$PageName)" only works for the first menu you are looking for, you need something more general.
Member 11762344 27-Aug-15 14:31pm    
@PIEBALDconsult i thought as much because when i removed About/menu node from the xml file, var_dump() returned an array of Help/menu node upon refresh. this disappeared however when i made a replacement. i just want to believe there's nothing wrong with my php code. but could your give me an idea of a more general xpath xpression ? thanks !
PIEBALDconsult 27-Aug-15 16:02pm    
I just had some success with "//menu[../../Home/menu/item/.=name(..)]"
Member 11762344 27-Aug-15 18:56pm    
thanks ! but its still unsuccessful for me. its frustrating over here .

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900