Thread: Xpath

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0

    Xpath


    Hi, my earlier post, I resolved the Pagination for XML. Now the issue is the data output is all the nodes in the XML. I need some help to use xpath to find some text within the codes and output in the pagination.

    ---Catalog.xml---

    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Catalog>
    <Category>
    <Name>Arts</Name>
    <Site>
    <Title>Photography 1</Title>
    <Description>This is Lesson 1 of Photography</Description>
    </Site>
    <Site>
    <Title>Photography 2</Title>
    <Description>This is Lesson 2 of Photography</Description>
    </Site>
    </Category>
    </Catalog>
    ----search.php----
    [PHP="Php"]

    class Pagination {

    protected

    //Configuration defaults
    $_arrConfig = array(
    'limit'=>10
    ,'page'=>1
    ,'basePath'=>'#'
    ,'label'=>'Items'
    ,'visiblePages'=>7
    ,'pageFlag'=>'{page}'
    )

    //Data to be passed to template
    ,$_arrTemplateData = array()

    //function to pass resolved offset and limit
    ,$_onPaginate

    //extra arguments to pass to to pagination callback such as data source or db connection
    ,$_arrArgs;

    public function __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {

    $this->_onPaginate = $onPaginate;
    $this->_arrArgs = $arrArgs;

    foreach($arrConfig as $strKey=>$mixValue) {
    if(array_key_exists($strKey,$this->_arrConfig)) {
    $this->_arrConfig[$strKey] = $mixValue;
    }
    }
    }

    public function paginate() {

    //Calculate page offset
    $intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];

    //Paginate and get number of found rows
    $intFoundRows = call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));

    //Assign template data
    $this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
    $this->_arrTemplateData['page'] = $this->_arrConfig['page'];
    $this->_arrTemplateData['offset'] = $intOffset;
    $this->_arrTemplateData['found_rows'] = $intFoundRows;
    $this->_arrTemplateData['total_pages'] = $intFoundRows < $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
    $this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
    $this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
    $this->_arrTemplateData['label'] = $this->_arrConfig['label'];
    $this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];

    //Return the pagination template
    return $this->display();
    }

    public function display() {
    extract($this->_arrTemplateData);

    if($total_pages <= $visible_pages) {
    $page_start = 1;
    $page_end = $total_pages;
    } else if($page <= ceil($visible_pages/2)) {
    $page_start = 1;
    $page_end = $visible_pages;
    } else if($page > ($total_pages - ceil($visible_pages/2))) {
    $page_start = $total_pages - (ceil(($visible_pages/2)*2)-1);
    $page_end = $total_pages;
    } else {
    $page_start = $page-(floor($visible_pages/2));
    $page_end = $page+(floor($visible_pages/2));
    }

    $return.= sprintf('<ul class="pagination">');

    $return.= sprintf(
    '<li class="first">%s%s%s</li>'
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
    ,'First'
    ,$page == 1?'':'</a>'
    );

    $return.= sprintf(
    '<li class="previous">%s%s%s</li>'
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
    ,'Previous'
    ,$page == 1?'':'</a>'
    );

    foreach(range($page_start,$page_end,1) as $i) {
    $return.= sprintf (
    '<li%s>%s%s%s</li>'
    ,$page == $i?' class="current"':''
    ,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
    ,$i
    ,$page == $i?'':'</a>'
    );
    }

    $return.= sprintf (
    '<li class="next">%s%s%s</li>'
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
    ,'Next'
    ,$page == $total_pages?'':'</a>'
    );

    $return.= sprintf(
    '<li class="last">%s%s%s</li>'
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
    ,'Last'
    ,$page == $total_pages?'':'</a>'
    );

    $return.= sprintf('</ul>');

    return $return;

    }

    }

    class Action {

    private $_objXML;
    private $_arrMessages = array();

    public function __construct() {

    $this->_objXML = simplexml_load_file("Catalog.xml");
    }

    public function paginate($offset,$limit) {

    $arrMessages = $this->_objXML->xpath('//Category[1]/Site/Description[contains(.,'Photo')] | //Category[1]/Site/Title[contains(.,'Photo')]');

    if(isset($arrMessages[$offset])) {
    for($i=0;$i<$limit;$i++) {

    if(!isset($arrMessages[($i+$offset)])) break;

    $this->_arrMessages[] = array(
    'Title'=>(string) $arrMessages[($i+$offset)]->Title.'</a>'
    ,'Description'=>(string) $arrMessages[($i+$offset)]->Description

    );
    }
    }

    // return number of total found rows
    return count($arrMessages);

    }

    public function getMessages() {
    return $this->_arrMessages;
    }

    }

    $action = new Action();

    $func = create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
    $pg = new Pagination($func,array(
    'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}'
    ,'pageFlag'=>'{replace_me_with_page}'
    ,'label'=>'Messages'
    ,'limit'=>10
    ,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
    ,'visiblePages'=>7
    ),array($action));

    [/PHP]


    ---Error from Browser---
    Parse error: syntax error, unexpected T_STRING in /home/a9729307/public_html/test.php on line 138 within

    class Action { }


    --------------------
    I checked xpath line is correct using online XML --> Xpath tools the code line is correct but not sure the method I used is correct?

    What I want to do:
    1. Search the node Title and Description for a word containing "Photo"
    2. Output the Title and Description NodeValue

    Can someone advice where I went wrong?

    Thanks and Merry Christmas.
  2. #2
  3. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,247
    Rep Power
    9400
    PHP Code:
    $this->_objXML->xpath('//Category[1]/Site/Description[contains(.,'Photo')] | //Category[1]/Site/Title[contains(.,'Photo')]'); 
    Check the quotes.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Originally Posted by requinix
    PHP Code:
    $this->_objXML->xpath('//Category[1]/Site/Description[contains(.,'Photo')] | //Category[1]/Site/Title[contains(.,'Photo')]'); 
    Check the quotes.
    PHP Code:
    $this->_objXML->xpath('//Category[1]/Site/Description[contains(.,"Photo")] | //Category[1]/Site/Title[contains(.,"Photo")]'); 

    Thanks requinix. I changed the query to double quotes, but now there is no error and the result is blank. Any idea? Is my class function correct?
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    I did a test at http://xpath.online-toolz.com/tools/xpath-editor.php

    XPATH Statment
    //Category[1]/Site/Description[contains(.,"Photo")] | //Category[1]/Site/Title[contains(.,"Photo")]


    Result:
    <Title>Photography 1</Title>
    -----------------------
    <Description>This is Lesson 1 of Photography</Description>
    -----------------------
    <Title>Photography 2</Title>
    -----------------------
    <Description>This is Lesson 2 of Photography</Description>


    When I insert the same code to my coding, no result shown.
  8. #5
  9. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,247
    Rep Power
    9400
    And where is the code that would output something?
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Originally Posted by requinix
    And where is the code that would output something?
    Sorry missed that out, here it is

    -------

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>Catalog</title>
    
    	<script type="text/javascript" src="java.js" ></script>
    	<link rel="stylesheet" href="paginate.css" type="text/css" />
    	<link rel="stylesheet" href="style.css" type="text/css" />
    
    </head>
    <body>
    
        <?php echo $pg->paginate(); ?>
        
        <?php
        if($action->getMessages()) {
    		echo '<ol>';
            foreach($action->getMessages() as $arrMessage) {
                printf(
                    '<h2><li>
                        <p><h3>%s</h2></p>
                        <p><h4>%s</h3></p>
    		<br />
                     </li>'
                     ,$arrMessage['Title']
                     ,$arrMessage['Description']
                );
            } 
            echo '</ol>';
        } else {
            echo "<p>No messages available</p>";
        }?>
    	
    	    <?php echo $pg->paginate(); ?>
      <br /><br />	
    	</div>
    
    </body>
    </html>
    ------

    I got a "No messages available" displayed.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Should I use SIMPLEXML and Xpath or should I use DOM and DOMXPATH
  14. #8
  15. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,247
    Rep Power
    9400
    IMO SimpleXML is easier but it doesn't really matter.

    What do you see if you do a View Source on the page? Have you made sure your php.ini is set up to show you errors during development?
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Sorry, where is this php.ini? I am using codelobster for php to develop. Cannot find this php.ini. Please guide me.
  18. #10
  19. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,247
    Rep Power
    9400
    phpinfo will tell you, right near the top of its huge output. While you're there look for the display_errors setting: it should be on.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Originally Posted by requinix
    phpinfo will tell you, right near the top of its huge output. While you're there look for the display_errors setting: it should be on.
    The setting is on.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    I did a simple test and got the xpath code correct as follows:

    ->xpath('//Title[contains(.,"Photo")]');

    The problem is when I use the same code in the pagination code,

    class Action{}

    It does not work.

    Any idea? Has it something to do with using class?
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Anyone able to advise which part of the coding is wrong?
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    25
    Rep Power
    0
    Yes, finally got this solve.

IMN logo majestic logo threadwatch logo seochat tools logo