Commits

Anonymous committed 3d0f06e

added (non-standard) methods: nonBlankChildNodes, firstNonBlankChild, nextNonBlankSibling, prevNonBlankSibling

Comments (0)

Files changed (4)

 
 sub childNodes {
     my $self = shift;
-    my @children = $self->_childNodes();
+    my @children = $self->_childNodes(0);
+    return wantarray ? @children : XML::LibXML::NodeList->new_from_ref(\@children , 1);
+}
+
+sub nonBlankChildNodes {
+    my $self = shift;
+    my @children = $self->_childNodes(1);
     return wantarray ? @children : XML::LibXML::NodeList->new_from_ref(\@children , 1);
 }
 
         RETVAL
 
 SV*
+nextNonBlankSibling( self )
+        xmlNodePtr self
+    PREINIT:
+        xmlNodePtr next;
+    CODE:
+        next = self->next;
+        while (next != NULL && xmlIsBlankNode(next))
+          next = next->next;
+        RETVAL = PmmNodeToSv( next,
+                              PmmOWNERPO(PmmPROXYNODE(self)) );
+    OUTPUT:
+        RETVAL
+
+
+SV*
 previousSibling( self )
         xmlNodePtr self
     ALIAS:
     OUTPUT:
         RETVAL
 
+SV*
+previousNonBlankSibling( self )
+        xmlNodePtr self
+    PREINIT:
+        xmlNodePtr prev;
+    CODE:
+        prev = self->prev;
+        while (prev != NULL && xmlIsBlankNode(prev))
+          prev = prev->prev;
+        RETVAL = PmmNodeToSv( prev,
+                              PmmOWNERPO(PmmPROXYNODE(self)) );
+    OUTPUT:
+        RETVAL
+
+
 void
-_childNodes( self )
+_childNodes( self, only_nonblank = 0 )
         xmlNodePtr self
+        int only_nonblank
     ALIAS:
         XML::LibXML::Node::getChildnodes = 1
     PREINIT:
             cld = self->children;
             xs_warn("childnodes start");
             while ( cld ) {
-                if( wantarray != G_SCALAR ) {
-                    element = PmmNodeToSv(cld, PmmOWNERPO(PmmPROXYNODE(self)) );
-                    XPUSHs(sv_2mortal(element));
+	        if ( !(only_nonblank && xmlIsBlankNode(cld)) ) {
+                  if( wantarray != G_SCALAR ) {
+                      element = PmmNodeToSv(cld, PmmOWNERPO(PmmPROXYNODE(self)) );
+                      XPUSHs(sv_2mortal(element));
+                  }
+                  len++;
                 }
                 cld = cld->next;
-                len++;
             }
         }
         if ( wantarray == G_SCALAR ) {
         RETVAL
 
 SV*
+firstNonBlankChild( self )
+        xmlNodePtr self
+    PREINIT:
+	xmlNodePtr child;
+    CODE:
+	child = self->children;
+        while (child !=NULL && xmlIsBlankNode(child))
+	  child = child->next;
+        RETVAL = PmmNodeToSv( child,
+                              PmmOWNERPO( PmmPROXYNODE(self) ) );
+    OUTPUT:
+        RETVAL
+
+SV*
 lastChild( self )
         xmlNodePtr self
     ALIAS:
                     <para>Returns the next sibling if any .</para>
                 </listitem>
             </varlistentry>
+
+            <varlistentry>
+                <term>nextNonBlankSibling</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$nextnode = $node-&gt;nextNonBlankSibling();</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>Returns the next non-blank sibling if any (a node is blank if it is a Text or CDATA node consisting of whitespace only). This method is not defined by DOM.</para>
+                </listitem>
+            </varlistentry>
         
 
         
                     <para>Analogous to <emphasis>getNextSibling</emphasis> the function returns the previous sibling if any.</para>
                 </listitem>
             </varlistentry>
+
+            <varlistentry>
+                <term>previousNonBlankSibling</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$prevnode = $node-&gt;previousNonBlankSibling();</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>Returns the previous non-blank sibling if any (a node is blank if it is a Text or CDATA node consisting of whitespace only). This method is not defined by DOM.</para>
+                </listitem>
+            </varlistentry>
         
 
         
 
                 <listitem>
                     <funcsynopsis>
-                        <funcsynopsisinfo>@childnodes = $node-&gt;childNodes;</funcsynopsisinfo>
-                    </funcsynopsis>
-
-                    <para><emphasis>getChildnodes</emphasis> implements a more intuitive interface to the childnodes of the current node. It enables you to pass
+                        <funcsynopsisinfo>@childnodes = $node-&gt;childNodes();</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para><emphasis>childNodes</emphasis> implements a more intuitive interface to the childnodes of the current node. It enables you to pass
                     all children directly to a <function>map</function> or <function>grep</function>. If this function is called in scalar context, a
                     <olink targetdoc="XML::LibXML::NodeList">XML::LibXML::NodeList</olink> object will be returned.</para>
                 </listitem>
             </varlistentry>
         
-
+            <varlistentry>
+                <term>nonBlankChildNodes</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>@childnodes = $node-&gt;nonBlankChildNodes();</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>This is like <emphasis>childNodes</emphasis>,
+		      but returns only non-blank nodes
+		      (where a node is blank if it is a Text or CDATA node consisting of whitespace only). This method is not defined by DOM.</para>
+                </listitem>
+            </varlistentry>
         
             <varlistentry>
                 <term>toString</term>
+# -*- cperl -*-
 # $Id$
 
 ##
 
 use Test;
 
-BEGIN { plan tests => 138 };
+BEGIN { plan tests => 166 };
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
-
+use strict;
+use warnings;
 my $xmlstring = q{<foo>bar<foobar/><bar foo="foobar"/><!--foo--><![CDATA[&foo bar]]></foo>};
 
 my $parser = XML::LibXML->new();
    ok($attr->toString() eq ' test="bar&foo;baz"');
 }
 
-{ 
-  for my $obj (qw(Document DocumentFragment Comment CDATASection PI Text)) { 
-    
-  } 
+{
+  my $doc = XML::LibXML->load_xml(string=><<'EOF');
+<r>
+  <a/>
+	  <b/>
+  <![CDATA[
+
+  ]]>
+  <!-- foo -->
+  <![CDATA[
+    x
+  ]]>
+  <?foo bar?>
+  <c/>
+  text
+</r>
+EOF
+  my $r = $doc->getDocumentElement;
+  ok($r);
+  my @nonblank = $r->nonBlankChildNodes;
+  ok(join(',',map $_->nodeName,@nonblank), 'a,b,#comment,#cdata-section,foo,c,#text' );
+  ok($r->firstChild->nodeName, '#text');
+
+  my @all = $r->childNodes;
+  ok(join(',',map $_->nodeName,@all), '#text,a,#text,b,#text,#cdata-section,#text,#comment,#text,#cdata-section,#text,foo,#text,c,#text' );
+
+  my $f = $r->firstNonBlankChild;
+  my $p;
+  ok($f->nodeName, 'a');
+  ok($f->nextSibling->nodeName, '#text');
+  ok($f->previousSibling->nodeName, '#text');
+  ok( !$f->previousNonBlankSibling );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->nodeName, 'b');
+  ok($f->nextSibling->nodeName, '#text');
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->isa('XML::LibXML::Comment'));
+  ok($f->nextSibling->nodeName, '#text');
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->isa('XML::LibXML::CDATASection'));
+  ok($f->nextSibling->nodeName, '#text');
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->isa('XML::LibXML::PI'));
+  ok($f->nextSibling->nodeName, '#text');
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->nodeName, 'c');
+  ok($f->nextSibling->nodeName, '#text');
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $p = $f;
+  $f=$f->nextNonBlankSibling;
+  ok($f->nodeName, '#text');
+  ok($f->nodeValue, "\n  text\n");
+  ok(!$f->nextSibling);
+  ok( $f->previousNonBlankSibling->isSameNode($p) );
+
+  $f=$f->nextNonBlankSibling;
+  ok(!defined $f);
+
 }