SitePoint Sponsor

User Tag List

Results 1 to 18 of 18
  1. #1
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    XML / XPath retrieve inner text of node?

    Hey all,

    I have the following xml schema:

    Code:
    <language name="Spanish" short="Es">
        <text key="Hello">
            Hola
        </text>
    
            <text key="House">
                    Casa
            </text>
    </language>
    Basically theres one <language> which contains lots of <text> elements, I want to retrieve the inner text for a <text> entry with the following function:

    PHP Code:
            function getText($key)
            {
                
    $doc = new DOMDocument();
                
                
    $doc->load($this->_file);
                
                
    $xpath = new DOMXPath($doc);
                
                
    $nodelist $xpath->query("language/text[@key='$key']");
                
                
    $node $nodelist->item(0);
                
                
    // Return inner text from node.
            

    Thats what i've got so far, except im not sure how to retrieve the inner text for a DomNode ?

    Anybody?

    Thanks, Matt.

  2. #2
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by matt-
    Thats what i've got so far, except im not sure how to retrieve the inner text for a DomNode ?
    You might just be able to do it as XPath...
    Code:
    string(language/text[@key='$key'])
    If that doesn't work have a look at the W3 site. They have a UML diagram somewhere showing all of the DOM methods and attributes. Probably something like getText() or somesuch. The model; should be pretty standard accross languages.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  3. #3
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If SleapEasy isn't too busy, you could ask for help ? Knows this stuff pretty well actually

  4. #4
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try this:

    PHP Code:
    $nodelist->item(0)->nodeValue
    Thanks,

    JT

  5. #5
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the responses all,

    lastcraft: no such luck

    Widow Maker: Thanks but I wouldn't want to intrude on someone that I dont know by private messaging questions to them

    seratonin: Parse Error on that line

  6. #6
    SitePoint Zealot patrikG's Avatar
    Join Date
    Aug 2003
    Location
    Sussex, UK
    Posts
    129
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm using this:
    PHP Code:
       function reduce_node_to_content($node,$attribute="content"){
           if (
    is_array($node->nodeset)){
               foreach(
    $node->nodeset as $content){
               
    $return[]    = stripslashes($content->{$attribute});
               }
           }
           else{
               return 
    $return[]=stripslashes($content->{$attribute});
           }
           return 
    $return;
       }
       
       
       function 
    parseXML($xml){
           
    //needs Sablotron  - xPath installed
           
    require_once('Pulse2/class_variable_conversion.inc.php');
           
    $convert    =    &new variableConversion();
       
           if (!empty(
    $xml)){
               
    $dom    =    domxml_open_mem($xml);
               
    $calcX =     $dom->xpath_new_context(); 
          
    $xml_parsed["notes"]         = $this->reduce_node_to_content($calcX->xpath_eval("//NOTES/text()"));
        }
           return 
    $xml_parsed;
       } 
    Last edited by patrikG; Jul 1, 2004 at 05:53.

  7. #7
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi PatrikG,

    Thanks for the post,
    Any examples of the xml schema you're using with that?

    Thanks,
    Matt.

  8. #8
    SitePoint Zealot patrikG's Avatar
    Join Date
    Aug 2003
    Location
    Sussex, UK
    Posts
    129
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hrmpf...was a bit of a rushed post. Here goes the XML:

    PHP Code:
     <?xml version="1.0" ?>
     <!DOCTYPE SERVICE SYSTEM "Service.dtd">
     <SERVICE ID="9">
              <CLIENT_HIERARCHY></CLIENT_HIERARCHY>
              <ACCOUNT_HANDLER></ACCOUNT_HANDLER>
              <NOTES></NOTES>
     
              <ALLOCATIONS>
                           <ALLOCATION ID="9">
                                       <TITLE></TITLE>
                                       <PHONE_NO></PHONE_NO>
                                       <DDI></DDI>
                                       <IVR_GROUP></IVR_GROUP>
                                       <DATE_START></DATE_START>
                                       <DATE_END></DATE_END>
                                       <CREATED_BY></CREATED_BY>
                                       <CREATED_DATE></CREATED_DATE>
                                       <UPDATED_BY></UPDATED_BY>
                                       <UPDATED_DATE></UPDATED_DATE>
                           </ALLOCATION>
              </ALLOCATIONS>
     
              <SCRIPTS>
                       <SCRIPT ID="9">
                               <NAME></NAME>
                               <CREATED_BY></CREATED_BY>
                               <CREATED_DATE></CREATED_DATE>
                               <UPDATED_BY></UPDATED_BY>
                               <UPDATED_DATE></UPDATED_DATE>
                               <DETAIL></DETAIL>
                       </SCRIPT>
              </SCRIPTS>
     </SERVICE>

  9. #9
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by matt-
    Widow Maker: Thanks but I wouldn't want to intrude on someone that I dont know by private messaging questions to them

    seratonin: Parse Error on that line
    What Seratonin posted should work.

    All DOM nodes (attributes, "tags", text nodes, etc.) have a nodeValue property. You should check your code, and the XPath query you're using is not properly formed (it should being with a /).

    I subclassed DomXPath to add a couple of helper functions for when I want to query an XML document and either retrieve only one node, or retrieve the node's value. This is so I don't have to deal with the DomNodeList when I know my query is only supposed to match 1 node.

    Feel free to use this if you want.

    PHP Code:
    /**
     * Extension of DomXPath which adds functions for retrieveing single 
     * nodes / nodevalues using XPath.
     *
     * @author        Neill Roy <>
     * @copyright    Neill Roy 2004
     * @license        GPL
     */

    class Pepper_XML_XPath extends DomXPath {

        
    /**
         * Constructor.
         *
         * @access    public
         * @param    object DomDocument
         * @return    void
         */
        
    public function __construct(DomDocument $domDoc) {
            
    parent::__construct($domDoc);
        } 
    // __construct()

        /**
         * Loads an XML file from the given URI.
         *
         * @access    public
         * @static
         * @param    string Uri of the XML document to load
         * @return    mixed FALSE if uri can't be loaded, Pepper_XML_XPath if it can.
         */
        
    public static function loadXPathURI($uri) {
            
    $doc = new DomDocument();
            if (!
    $doc->load($uri)) {
                return 
    FALSE;
            }
            return new 
    Pepper_XML_XPath($doc);
        } 
    // loadXPathURI()

        /**
         * This is a helper method for use with XPath queries that will retrieve 1 
         * (one) matching node's value. If there is more or less that 1 matches the method
         * will return FALSE, otherwise the single node's value will be returned.
         *
         * @access    public
         * @param    string XPath query string
         * @return    mixed
         */
        
    public function getNodeValue($qry) {
            if (!
    $node $this->getNode($qry)) {
                return 
    FALSE;
            }
            return 
    $node->nodeValue;
        } 
    // getNodeValue()

        /**
         * This is a helper method for use with XPath queries that will retrieve 1 
         * (one) matching node. If there is more or less that 1 matches the method
         * will return FALSE, otherwise the single node will be returned.
         *
         * @access    public
         * @param    string XPath query string
         * @return    mixed
         */
        
    public function getNode($qry) {
            
    // There is no way to retrieve the size of a DOMNodeList
            // so we iterate over it and if we only do one iteration return
            // the DOMNode in the DOMNodeList otherwise there are
            // not enough or to many results.
            
    $i 0;
            foreach (
    $this->query($qry) as $result) {
                
    $i++;
                
    $last $result;
                if (
    $i == 2) {
                    return 
    FALSE;
                }
            }
            if (
    $i == 1) {
                return 
    $last;
            }
        } 
    // getNode()

    // Pepper_XML_XPath 
    quick usage examples :

    PHP Code:
    $store Pepper_XML_XPath::loadXPathURI(self::COMMAND_MAP_URI);
    $store->getNodeValue('/map/command[@id="' $id '"]/somenode'); 
    This method can also be used to get the value of other node types (attributes, text)

    e.g.

    PHP Code:
    $xml = new DomDocument()
    $xml->load('document.xml');
    $store = new Pepper_XML_XPath($xml);
    echo 
    $store->getNodeValue('/map/command[@id="' $id '"]/somenode');
    echo 
    $store->getNodeValue('/map/command[@id="' $id '"]/@someattribute');
    echo 
    $store->getNodeValue('/map/command[@id="' $id '"]/text()'); 
    Hope that helps.

    If you need any more help or want me to explain it a bit better (I'm prone to rambling on at times) just ask.
    Always open to question or ridicule

  10. #10
    SitePoint Evangelist
    Join Date
    Dec 2003
    Location
    Arizona
    Posts
    411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is the full code listing that worked for me:

    Code:
    <?xml version="1.0"?>
    <language name="Spanish" short="Es">
    	<text key="Hello">Hola</text>
    	<text key="House">Casa</text>
    </language>
    PHP Code:
    <?php
    $doc 
    = new DOMDocument();
    $doc->load("language.xml");
    $xpath = new DOMXPath($doc);
    $nodelist $xpath->query("/language/text[@key='Hello']");
    echo 
    $nodelist->item(0)->nodeValue;
    ?>
    Please let me know if you have any more problems with it.

    Thanks,

    JT

  11. #11
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks very much sleapeasy

    I'll just give serantonin's solution a go first though, but thats certainly helpful if we cannot resolve this.

    The complete code I have is:

    PHP Code:
    <?
        
    class Language
        
    {
            var 
    $language 'english';
            var 
    $file '../languages/english.xml';
            
            function 
    Language()
            {
            
            }
            
            function 
    getText($key)
            {
                
    $doc = new DOMDocument(); 
                
    $doc->load($this->file); 
                
    $xpath = new DOMXPath($doc); 
                
    $nodelist $xpath->query("/language/text[@key='$key']"); 
                return 
    $nodelist->item(0)->nodeValue;     
            }
            
            function 
    setLanguage($language$file)
            {
                
    $this->language $language;
                
    $this->file $file;
            }
        }
    ?>
    And calling the script:

    PHP Code:
    <?
        
    include('classes/language.class.inc');
        
    $language = new Language;
                
        die(
    $language->getText("Hello"));
    ?>
    And its giving me a parse error on

    return $nodelist->item(0)->nodeValue;

    Any ideas?

    Thanks
    Matt.

  12. #12
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well I studied your code and I was pretty sure it was fine - so I tested it myself and it worked perfectly.

    My setup: PHP 5RC3, Apache 2.0.48, libxml 2.5.11, Linux.

    I'm stumped as to why you get a parse error on that line.
    Always open to question or ridicule

  13. #13
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just consulted my tech support, and they've told me the server has the following:

    xml
    XML Support active
    XML Namespace Support active
    EXPAT Version expat_1.95.2

    domxml
    DOM/XML enabled
    libxml Version 2.4.19
    XPath Support enabled
    XPointer Support enabled

    Is all that ok?

  14. #14
    SitePoint Zealot sleepeasy's Avatar
    Join Date
    Sep 2003
    Location
    Bristol, UK
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for the late reply. If you haven't solved your problem yet:

    What version of PHP are you using?

    Ask your tech support if you're not sure or use phpversion.

    You could also try asking in the php.xml.dev newsgroup - give them all the info you gave above along with the version number and I'm sure they'll be of more help.
    Always open to question or ridicule

  15. #15
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey,

    Sorry for the late reply, the project got put aside for a while and I totally forgot

    The PHP version is: 4.1.2

    Matt.

  16. #16
    SitePoint Zealot
    Join Date
    Jun 2003
    Location
    Elsewhere
    Posts
    107
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Then you'll probably need to change
    PHP Code:
    return $nodelist->item(0)->nodeValue
    to
    PHP Code:
    $item $nodelist->item(0);
    return 
    $item->nodeValue
    HTH,

    Azmo

  17. #17
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That looks promising, i'll give it a go tomorrow, thanks.

  18. #18
    SitePoint Evangelist
    Join Date
    Nov 2003
    Location
    England
    Posts
    540
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, now it seems to be going backward..

    I have this in a language class:

    PHP Code:

    function getText($key)
                   {
                       
    $doc = new DOMDocument();
                       
                       
    $doc->loadXML("<bleh></bleh>");
                       
                       
    //$doc->load("spanish.xml");
                       
                       
    $xpath = new DOMXPath($doc);
                            
                            
    $nodelist $xpath->query("/language/text[@key='$key']");
                            
                            
    $item $nodelist->item(0);
                            
                            return 
    $item->nodeValue;  
                    } 
    And im getting

    Fatal error: Call to undefined function: loadxml() in public_html/classes/language.class.inc on line 59

    same for load();



Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •