global.user Posted February 3, 2009 Share Posted February 3, 2009 Hi allI was coding a php page that has to display some XML and I found out that I still hadn't found a simpler way to print values using XPATH.What I'm using: <?php $nodes = $xp->query("/calendar/year[@year = '$year']/month[@month = '$month']/days/day[@day = '$day']/color"); foreach ($nodes as $node) { print $node->textContent . " "; } ?> What I want to do... something like, define a function once, then calling it with the parameters... looks better and i'm less capable of errors this way.I haven't coded for a while (enjoying my summer holidays), but I do remember having spent hours on this without finding anything...So, has anyone an idea ?ThxGU Link to comment Share on other sites More sharing options...
boen_robot Posted February 3, 2009 Share Posted February 3, 2009 I have four actually:1. An error prone one, but useful when you're sure you want to use it is the evaluate() method: <?php echo $xp->evaluate("/calendar/year[@year = '$year']/month[@month = '$month']/days/day[@day = '$day']/color"); ?> 2. A less error prone, but potentially confusing way is to do what XSLT does with value-of - use the first appropriate result directly: <?php $xp->query("/calendar/year[@year = '$year']/month[@month = '$month']/days/day[@day = '$day']/color")->item(0)->nodeValue; ?> It's potentially confusing because if the XPath maches more than one node, only the first one is displayed.3. If you want to print the whole list instead, you may go for a function like: function printDOMNodeList(DOMNodeList $nodes) { foreach ($nodes as $node) { //Replace with whatever you want to happen on each node print $node->textContent . " "; }} And then do: printDOMNodeList($xp->query("/calendar/year[@year = '$year']/month[@month = '$month']/days/day[@day = '$day']/color")); BTW, that last function could also be reused for other places where DOMNodeList is returned, like: printDOMNodeList($dom->getElementsByTagName('year')); 4. An alternative way would be to extend the DOMNodeList, register the extender, and use that. For example: class myDOMNodeList extends DOMNodeList { function __toString() { $return = ''; foreach ($this as $node) { //Replace with whatever you want to happen on each node $return .= $node->textContent . " "; } return $return; }} And then do: $dom->registerNodeClass('DOMNodeList', 'myDOMNodeList');//just this once//assuming $xp is binded to the same DOMDocumentecho $xp->query("/calendar/year[@year = '$year']/month[@month = '$month']/days/day[@day = '$day']/color"); This implementation can too be used on other places where DOMNodeList is returned, like: echo $dom->getElementsByTagName('year'); (assuming you've registered the extender as before) Link to comment Share on other sites More sharing options...
global.user Posted February 3, 2009 Author Share Posted February 3, 2009 Wow. OK, thanks. I'll test that right now. Thx again ! Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.