Anonymous avatar Anonymous committed d4f6610

added $node_or_xpc->exists($xpath)

Comments (0)

Files changed (7)

     }
 }
 
+sub exists {
+    my ($node, $xpath) = @_;
+    my (undef, $value) = $node->_find($xpath,1);
+    return $value;
+}
+
 sub findvalue {
     my ($node, $xpath) = @_;
     my $res;
-    eval {
-        $res = $node->find($xpath);
-    };
-    if  ( $@ ) {
-        die $@;
+    $res = $node->find($xpath);
+    return $res->to_literal->value;
+}
+
+sub findbool {
+    my ($node, $xpath) = @_;
+    my ($type, @params) = $node->_find($xpath,1);
+    if ($type) {
+        return $type->new(@params);
     }
-    return $res->to_literal->value;
+    return undef;
 }
 
 sub find {
     my ($node, $xpath) = @_;
-    my ($type, @params) = $node->_find($xpath);
+    my ($type, @params) = $node->_find($xpath,0);
     if ($type) {
         return $type->new(@params);
     }
 
 
 void
-_find( pnode, pxpath )
+_find( pnode, pxpath, to_bool )
         SV* pnode
         SV * pxpath
+	int to_bool
     PREINIT:
         xmlNodePtr node = PmmSvNode(pnode);
         ProxyNodePtr owner = NULL;
 
         INIT_ERROR_HANDLER;
         if (comp) {
-          found = domXPathCompFind( node, comp );
+          found = domXPathCompFind( node, comp, to_bool );
         } else {
-          found = domXPathFind( node, xpath );
+          found = domXPathFind( node, xpath, to_bool );
           xmlFree( xpath );
         }
         CLEANUP_ERROR_HANDLER;
 
         INIT_ERROR_HANDLER;
         if (comp) {
-            nodelist = domXPathCompSelect( node, comp );
+	    nodelist = domXPathCompSelect( node, comp );
         } else {
-            nodelist = domXPathSelect( node, xpath );
+	    nodelist = domXPathSelect( node, xpath );
             xmlFree(xpath);
         }
         CLEANUP_ERROR_HANDLER;
 
         PUTBACK ;
         if (comp) {
-          found = domXPathCompFindCtxt( ctxt, comp );
+          found = domXPathCompFindCtxt( ctxt, comp, 0 );
         } else {
-            found = domXPathFindCtxt( ctxt, xpath );
-            xmlFree(xpath);
+	  found = domXPathFindCtxt( ctxt, xpath, 0 );
+	  xmlFree(xpath);
         }
         SPAGAIN ;
 
         }
 
 void
-_find( pxpath_context, pxpath )
+_find( pxpath_context, pxpath, to_bool )
         SV * pxpath_context
         SV * pxpath
+        int to_bool
     PREINIT:
         xmlXPathContextPtr ctxt = NULL;
         ProxyNodePtr owner = NULL;
         INIT_ERROR_HANDLER;
         PUTBACK ;
         if (comp) {
-          found = domXPathCompFindCtxt( ctxt, comp );
+          found = domXPathCompFindCtxt( ctxt, comp, to_bool );
         } else {
-            found = domXPathFindCtxt( ctxt, xpath );
-            xmlFree(xpath);
+	  found = domXPathFindCtxt( ctxt, xpath, to_bool );
+	  xmlFree(xpath);
         }
         SPAGAIN ;
         CLEANUP_ERROR_HANDLER;

lib/XML/LibXML/XPathContext.pm

 sub findnodes {
     my ($self, $xpath, $node) = @_;
 
-    my @nodes = $self->_guarded_find_call('_findnodes', $xpath, $node);
+    my @nodes = $self->_guarded_find_call('_findnodes', $node, $xpath);
 
     if (wantarray) {
         return @nodes;
 sub find {
     my ($self, $xpath, $node) = @_;
 
-    my ($type, @params) = $self->_guarded_find_call('_find', $xpath, $node);
+    my ($type, @params) = $self->_guarded_find_call('_find', $node, $xpath,0);
 
     if ($type) {
         return $type->new(@params);
     return undef;
 }
 
+sub exists {
+    my ($self, $xpath, $node) = @_;
+    my (undef, $value) = $self->_guarded_find_call('_find', $node, $xpath,1);
+    return $value;
+}
+
 sub findvalue {
     my $self = shift;
     return $self->find(@_)->to_literal->value;
 }
 
 sub _guarded_find_call {
-    my ($self, $method, $xpath, $node) = @_;
+    my ($self, $method, $node)=(shift,shift,shift);
 
     my $prev_node;
     if (ref($node)) {
     }
     my @ret;
     eval {
-        @ret = $self->$method($xpath);
+        @ret = $self->$method(@_);
     };
     $self->_free_node_pool;
     $self->setContextNode($prev_node) if ref($node);
 use Test;
 use strict;
 
-BEGIN { plan tests => 48 };
+BEGIN { plan tests => 52 };
 use XML::LibXML;
 
 my $xmlstring = <<EOSTR;
 
     $result = $doc->find( "contains(/foo/bar[3], 'test 1')" );
     ok( $result == 0 );
+
+    ok( $doc->exists("/foo/bar[2]") );
+    ok( $doc->exists("/foo/bar[3]"), 0 );
+
+    my ($node) = $doc->findnodes("/foo/bar[1]" );
+    ok( $node );
+    ok ($node->exists("following-sibling::bar"));
 }
 
 {

t/30xpathcontext.t

 use Test;
-BEGIN { plan tests => 79 };
+BEGIN { plan tests => 82 };
 
 use XML::LibXML;
 use XML::LibXML::XPathContext;
 ok($xc->findnodes('/xxx:foo')->pop->nodeName eq 'foo');
 ok($xc->findnodes($compiled)->pop->nodeName eq 'foo');
 ok($xc->lookupNs('xxx') eq 'http://example.com/foobar');
+ok($xc->exists('//xxx:bar/@a'));
+ok($xc->exists('//xxx:bar/@b'),0);
+ok($xc->exists('xxx:bar',$doc1->getDocumentElement));
 
 # test unregisterNs()
 $xc->unregisterNs('xxx');
  **/
 
 xmlXPathObjectPtr
-domXPathFind( xmlNodePtr refNode, xmlChar * path ) {
+domXPathFind( xmlNodePtr refNode, xmlChar * path, int to_bool ) {
     xmlXPathObjectPtr res = NULL;
     xmlXPathCompExprPtr comp;
     comp = xmlXPathCompile( path );
     if ( comp == NULL ) {
         return NULL;
     }
-    res = domXPathCompFind(refNode,comp);
+    res = domXPathCompFind(refNode,comp,to_bool);
     xmlXPathFreeCompExpr(comp);
     return res;
 }
 
 xmlXPathObjectPtr
-domXPathCompFind( xmlNodePtr refNode, xmlXPathCompExprPtr comp ) {
+domXPathCompFind( xmlNodePtr refNode, xmlXPathCompExprPtr comp, int to_bool ) {
     xmlXPathObjectPtr res = NULL;
   
     if ( refNode != NULL && comp != NULL ) {
         xmlXPathRegisterFunc(ctxt,
                              (const xmlChar *) "document",
                              perlDocumentFunction);
-       
-        res = xmlXPathCompiledEval(comp, ctxt);
-
+	if (to_bool) {
+	  int val = xmlXPathCompiledEvalToBoolean(comp, ctxt);
+	  res = xmlXPathNewBoolean(val);
+	} else {
+	  res = xmlXPathCompiledEval(comp, ctxt);
+	}
         if (ctxt->namespaces != NULL) {
             xmlFree( ctxt->namespaces );
         }
     xmlNodeSetPtr rv = NULL;
     xmlXPathObjectPtr res = NULL;
   
-    res = domXPathFind( refNode, path );
+    res = domXPathFind( refNode, path, 0 );
     
     if (res != NULL) {
             /* here we have to transfer the result from the internal
     xmlNodeSetPtr rv = NULL;
     xmlXPathObjectPtr res = NULL;
   
-    res = domXPathCompFind( refNode, comp );
+    res = domXPathCompFind( refNode, comp, 0 );
     
     if (res != NULL) {
             /* here we have to transfer the result from the internal
  **/
 
 xmlXPathObjectPtr
-domXPathFindCtxt( xmlXPathContextPtr ctxt, xmlChar * path ) {
+domXPathFindCtxt( xmlXPathContextPtr ctxt, xmlChar * path, int to_bool ) {
     xmlXPathObjectPtr res = NULL;
     if ( ctxt->node != NULL && path != NULL ) {
         xmlXPathCompExprPtr comp;
         if ( comp == NULL ) {
             return NULL;
         }
-        res = domXPathCompFindCtxt(ctxt,comp);
+        res = domXPathCompFindCtxt(ctxt,comp,to_bool);
         xmlXPathFreeCompExpr(comp);
     }
     return res;
 }
 
 xmlXPathObjectPtr
-domXPathCompFindCtxt( xmlXPathContextPtr ctxt, xmlXPathCompExprPtr comp ) {
+domXPathCompFindCtxt( xmlXPathContextPtr ctxt, xmlXPathCompExprPtr comp, int to_bool ) {
     xmlXPathObjectPtr res = NULL;
     if ( comp != NULL && ctxt->node != NULL && comp != NULL ) {
         xmlDocPtr tdoc = NULL;
 
             ctxt->node->doc = tdoc;
         }
-       
-        res = xmlXPathCompiledEval(comp, ctxt);
-
+	if (to_bool) {
+	  int val = xmlXPathCompiledEvalToBoolean(comp, ctxt);
+	  res = xmlXPathNewBoolean(val);
+	} else {
+	  res = xmlXPathCompiledEval(comp, ctxt);
+	}
         if ( tdoc != NULL ) {
             /* after looking through a fragment, we need to drop the
                fake document again */
     xmlNodeSetPtr rv = NULL;
     xmlXPathObjectPtr res = NULL;
   
-    res = domXPathFindCtxt( ctxt, path );
+    res = domXPathFindCtxt( ctxt, path, 0 );
     
     if (res != NULL) {
             /* here we have to transfer the result from the internal
 domXPathSelect( xmlNodePtr refNode, xmlChar * xpathstring );
 
 xmlXPathObjectPtr
-domXPathFind( xmlNodePtr refNode, xmlChar * xpathstring );
+domXPathFind( xmlNodePtr refNode, xmlChar * xpathstring, int to_bool );
 
 xmlNodeSetPtr
 domXPathCompSelect( xmlNodePtr refNode, xmlXPathCompExprPtr comp );
 
 xmlXPathObjectPtr
-domXPathCompFind( xmlNodePtr refNode, xmlXPathCompExprPtr comp );
+domXPathCompFind( xmlNodePtr refNode, xmlXPathCompExprPtr comp, int to_bool );
 
 xmlNodeSetPtr
 domXPathSelectCtxt( xmlXPathContextPtr ctxt, xmlChar * xpathstring );
 
 xmlXPathObjectPtr
-domXPathFindCtxt( xmlXPathContextPtr ctxt, xmlChar * xpathstring );
+domXPathFindCtxt( xmlXPathContextPtr ctxt, xmlChar * xpathstring, int to_bool );
 
 xmlXPathObjectPtr
-domXPathCompFindCtxt( xmlXPathContextPtr ctxt, xmlXPathCompExprPtr comp );
+domXPathCompFindCtxt( xmlXPathContextPtr ctxt, xmlXPathCompExprPtr comp, int to_bool );
 
 #endif
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.