Commits

pa...@9ae0c189-cd1f-4510-a509-f4891f5cf20d  committed 77dac8f

- get/setAttributeNS now handles xmnls declarations just like set/getAttribute
- updated section on namespaces in the DOM documentation page with conformance information
- all .pm modules have version now (updated from LibXML.pm by 'make version')
- more tests

  • Participants
  • Parent commits 1b4e753

Comments (0)

Files changed (15)

 Revision history for Perl extension XML::LibXML
 
-1.61pre 
+1.61
    - get{Elements,Children}By{TagName,TagNameNS,LocalName} now
      obey wildcards '*', getChildrenByLocalName was added.
    - XML::LibXML::XPathContext merged in
-   - added setNamespaceDecl{URI,Prefix}
    - many new tests added
    - the module should now be fully compatibile with libxml2 >= 2.6.16
      (some older versions compile but have problems with namespaced attributes)
    - threads test skipped by default
+   - documentation updates (namely DOM namespace conformance in XML::LibXML::DOM)
+   - added setNamespaceDecl{URI,Prefix}
+   - get/setAttribute(NS)? implementation made xmlns aware
+   - all sub-modules have the same version as XML::LibXML
 
 1.60
    - getElementsById corrected to getElementById and the old name kept
 
 use XML::LibXML::Common qw(:encoding :libxml);
 
+use constant XML_XMLNS_NS => 'http://www.w3.org/2000/xmlns/';
+use constant XML_XML_NS => 'http://www.w3.org/XML/1998/namespace';
+
 use XML::LibXML::NodeList;
 use XML::LibXML::XPathContext;
 use IO::Handle; # for FH reads called as methods
 
-
-$VERSION = "1.61";
-require Exporter;
-require DynaLoader;
-
-@ISA = qw(DynaLoader Exporter);
+BEGIN {
+  $VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+  require Exporter;
+  require DynaLoader;
+  @ISA = qw(DynaLoader Exporter);
 
 #-------------------------------------------------------------------------#
 # export information                                                      #
                            XML_XINCLUDE_START
                            encodeToUTF8
                            decodeFromUTF8
+		           XML_XMLNS_NS
+		           XML_XML_NS
                           )],
                 libxml => [qw(
                            XML_ELEMENT_NODE
                                 encodeToUTF8
                                 decodeFromUTF8
                                )],
+		ns => [qw(
+		           XML_XMLNS_NS
+		           XML_XML_NS		    
+		 )],
                );
 
 @EXPORT_OK = (
 #-------------------------------------------------------------------------#
 bootstrap XML::LibXML $VERSION;
 
+} # BEGIN
+
 #-------------------------------------------------------------------------#
 # parser constructor                                                      #
 #-------------------------------------------------------------------------#
 
 use vars qw(@ISA);
 @ISA = ('XML::LibXML::Node');
+use XML::LibXML qw(:ns :libxml);
+use Carp;
 
 sub setNamespace {
     my $self = shift;
 sub setAttribute {
     my ( $self, $name, $value ) = @_;
     if ( $name =~ /^xmlns(?::|$)/ ) {
-        # user wants to set a namespace ...
+      # user wants to set the special attribute for declaring XML namespace ...
 
-        (my $prefix = $name )=~s/^xmlns:?//;
-        my $nn = $self->nodeName;
-        if ( $nn =~ /^$prefix\:/ ) {
-	  $self->setNamespaceDeclURI($prefix,$value) &&
-	    $self->setNamespace($value,$prefix,1);
-        }
-        else {
-	  # use a ($active = 0) namespace
-	  $self->setNamespaceDeclURI($prefix, $value) ||
-	    $self->setNamespace($value,$prefix,0);
-        }
+      # this is fine but not exactly DOM conformant behavior, btw (according to DOM we should
+      # probably declare an attribute which looks like XML namespace declaration
+      # but isn't)
+      (my $nsprefix = $name )=~s/^xmlns:?//;
+      my $nn = $self->nodeName;
+      if ( $nn =~ /^\Q${nsprefix}\E:/ ) {
+	# the element has the same prefix
+	$self->setNamespaceDeclURI($nsprefix,$value) ||
+	  $self->setNamespace($value,$nsprefix,1);
+        ##
+        ## We set the namespace here.
+        ## This is helpful, as in:
+        ##
+        ## |  $e = XML::LibXML::Element->new('foo:bar');
+        ## |  $e->setAttribute('xmlns:foo','http://yoyodine')
+        ##
+      }
+      else {
+	# just modify the namespace
+	$self->setNamespaceDeclURI($nsprefix, $value) ||
+	  $self->setNamespace($value,$nsprefix,0);
+      }
     }
     else {
         $self->_setAttribute($name, $value);
     }
 }
 
+sub getAttributeNS {
+    my $self = shift;
+    my ($nsURI, $name) = @_;
+    croak("invalid attribute name") if !defined($name) or $name eq q{};
+    if ( defined($nsURI) and $nsURI eq XML_XMLNS_NS ) {
+	$self->_getNamespaceDeclURI($name eq 'xmlns' ? undef : $name);
+    }
+    else {
+        $self->_getAttributeNS(@_);
+    }
+}
+
+sub setAttributeNS {
+  my ($self, $nsURI, $qname, $value)=@_;
+  unless (defined $qname and length $qname) {
+    croak("bad name");
+  }
+  if (defined($nsURI) and $nsURI eq XML_XMLNS_NS) {
+    if ($qname !~ /^xmlns(?::|$)/) {
+      croak("NAMESPACE ERROR: Namespace declartions must have the prefix 'xmlns'");
+    }
+    $self->setAttribute($qname,$value); # see implementation above
+    return;
+  }
+  if ($qname=~/:/ and not (defined($nsURI) and length($nsURI))) {
+    croak("NAMESPACE ERROR: Attribute without a prefix cannot be in a namespace");
+  }
+  if ($qname=~/^xmlns(?:$|:)/) {
+    croak("NAMESPACE ERROR: 'xmlns' prefix and qualified-name are reserved for the namespace ".XML_XMLNS_NS);
+  }
+  if ($qname=~/^xml:/ and not (defined $nsURI and $nsURI eq XML_XML_NS)) {
+    croak("NAMESPACE ERROR: 'xml' prefix is reserved for the namespace ".XML_XML_NS);
+  }
+  $self->_setAttributeNS( defined $nsURI ? $nsURI : undef, $qname, $value );
+}
+
 sub getElementsByTagName {
     my ( $node , $name ) = @_;
     my $xpath = $name eq '*' ? "descendant::*" : "descendant::*[name()='$name']";
     my ( $node, $name ) = @_;
     my @nodes;
     if ($name eq '*') {
-      @nodes = grep { $_->nodeType == XML::LibXML::XML_ELEMENT_NODE() }
+      @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() }
 	$node->childNodes();
     } else {
       @nodes = grep { $_->nodeName eq $name } $node->childNodes();
     my ( $node, $name ) = @_;
     my @nodes;
     if ($name eq '*') {
-      @nodes = grep { $_->nodeType == XML::LibXML::XML_ELEMENT_NODE() }
+      @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() }
 	$node->childNodes();
     } else {
-      @nodes = grep { $_->nodeType == XML::LibXML::XML_ELEMENT_NODE() and
+      @nodes = grep { $_->nodeType == XML_ELEMENT_NODE() and
 		      $_->localName eq $name } $node->childNodes();
     }
     return wantarray ? @nodes : XML::LibXML::NodeList->new_from_ref(\@nodes, 1);
         RETVAL
 
 SV *
-getAttributeNS( self, namespaceURI, attr_name )
+_getAttributeNS( self, namespaceURI, attr_name )
         xmlNodePtr self
         SV * namespaceURI
         SV * attr_name
         RETVAL
 
 void
-setAttributeNS( self, namespaceURI, attr_name, attr_value )
+_setAttributeNS( self, namespaceURI, attr_name, attr_value )
         xmlNodePtr self
         SV * namespaceURI
         SV * attr_name
         }
 
         if ( nsURI && xmlStrlen(nsURI) && !ns ) {
-            xs_warn( "bad ns attribute!" );
+	  if ( prefix ) xmlFree( prefix );
+	  if ( nsURI ) xmlFree( nsURI );
+	  xmlFree( name );
+	  xmlFree( value );
+	  croak( "bad ns attribute!" );
         }
         else {
             /* warn( "set attribute %s->%s", name, value ); */
    return $script;
 }
 
+sub MY::postamble {
+  return <<'MAKE_FRAG';
+
+# used to update version numbers in all modules
+version:=$(shell grep '\# VERSION TEMPLATE' $(VERSION_FROM))
+version:
+	@echo "New version line: $(version)"
+	@perl -pi~ -e '$$_=q($(version))."\n" if /#\ VERSION TEMPLATE/ ' $(TO_INST_PM)
+
+MAKE_FRAG
+}
+
+
 # -------------------------------------------------------------------------- #
 
 # -------------------------------------------------------------------------- #

File docs/libxml.dbk

         <sect1>
             <title>Description</title>
 
-            <para>XML::LibXML provides an lightwight interface to <emphasis>modify</emphasis> a node of the document tree generated by the XML::LibXML parser.
-            This interface follows as far as possible the DOM Level 3 specification. Additionally to the specified functions the XML::LibXML supports some
-            functions that are more handy to use in the perl environment.</para>
-
-            <para>One also has to remember, that XML::LibXML is an interface to libxml2 nodes which actually reside on the C-Level of XML::LibXML. This means
-            each node is a reference to a structure different than a perl hash or array. The only way to access these structure's values is through the DOM
-            interface provided by XML::LibXML. This also means, that one <emphasis>can't</emphasis> simply inherit a XML::LibXML node and add new member
-            variables as they were hash keys.</para>
-
-            <para>The DOM interface of XML::LibXML does not intend to implement a full DOM interface as it is done by XML::GDOME and used for full featured
-            application. Moreover, it offers an simple way to build or modify documents that are created by XML::LibXML's parser.</para>
-
-            <para>Another target of the XML::LibXML interface is to make the interfaces of libxml2 available to the perl community. This includes also some
-            workarounds to some features where libxml2 assumes more control over the C-Level that most perl users don't have.</para>
-
-            <para>One of the most important parts of the XML::LibXML DOM interface is, that the interfaces try do follow the DOM Level 3 specification rather
-            strictly. This means the interface functions are named as the DOM specification says and not what widespread Java interfaces claim to be standard.
-            Although there are several functions that have only a singular interface that conforms to the DOM spec XML::LibXML provides an additional Java style
-            alias interface.</para>
-
-            <para>Also there are some function interfaces left over from early stages of XML::LibXML for compatibility reasons. These interfaces are for
-            compatibility reasons <emphasis>only</emphasis>. They might disappear in one of the future versions of XML::LibXML, so a user is requested to switch
-            over to the official functions.</para>
-
-            <para>More recent versions of perl (e.g. 5.6.1 or higher) support special flags to disinguish between UTF-8 and so called binary data. XML::LibXML
-            provides for these versions functionality to make efficient use of these flags: If a document has set an encoding other than UTF-8 all strings that
-            are not already in UTF-8 are implicitly encoded from the document encoding to UTF-8. On output these strings are commonly returned as UTF-8 unless a
-            user does request explicitly the original (aka. document) encoding.</para>
-
-            <para>Older version of perl (such as 5.00503 or less) do not support these flags. If XML::LibXML is build for these versions, all strings have to
-            get encoded to UTF-8 manualy before they are passed to any DOM functions.</para>
-
-            <para><emphasis>NOTE:</emphasis> XML::LibXML's magic encoding may not work on all plattforms. Some platforms are known to have a broken iconv(),
-            which is partly used by libxml2. To test if your platform works correctly with your language encoding, build a simple document in the particular
-            encoding and try to parse it with XML::LibXML. If your document gets parsed with out causing any segmentation faults, bus errors or whatever your OS
-            throws. An example for such a test can be found in test 19encoding.t of the distribution.</para>
+            <para>XML::LibXML provides an lightwight interface to
+            <emphasis>modify</emphasis> a node of the document tree
+            generated by the XML::LibXML parser.  This interface
+            follows as far as possible the DOM Level 3
+            specification. Additionally to the specified functions the
+            XML::LibXML supports some functions that are more handy to
+            use in the perl environment.</para>
+
+            <para>One also has to remember, that XML::LibXML is an
+            interface to libxml2 nodes which actually reside on the
+            C-Level of XML::LibXML. This means each node is a
+            reference to a structure different than a perl hash or
+            array. The only way to access these structure's values is
+            through the DOM interface provided by XML::LibXML. This
+            also means, that one <emphasis>can't</emphasis> simply
+            inherit a XML::LibXML node and add new member variables as
+            they were hash keys.</para>
+
+            <para>The DOM interface of XML::LibXML does not intend to
+            implement a full DOM interface as it is done by XML::GDOME
+            and used for full featured application. Moreover, it
+            offers an simple way to build or modify documents that are
+            created by XML::LibXML's parser.</para>
+
+            <para>Another target of the XML::LibXML interface is to
+            make the interfaces of libxml2 available to the perl
+            community. This includes also some workarounds to some
+            features where libxml2 assumes more control over the
+            C-Level that most perl users don't have.</para>
+
+            <para>One of the most important parts of the XML::LibXML
+            DOM interface is, that the interfaces try do follow the
+            DOM Level 3 specification rather strictly. This means the
+            interface functions are named as the DOM specification
+            says and not what widespread Java interfaces claim to be
+            standard.  Although there are several functions that have
+            only a singular interface that conforms to the DOM spec
+            XML::LibXML provides an additional Java style alias
+            interface.</para>
+
+            <para>Also there are some function interfaces left over
+            from early stages of XML::LibXML for compatibility
+            reasons. These interfaces are for compatibility reasons
+            <emphasis>only</emphasis>. They might disappear in one of
+            the future versions of XML::LibXML, so a user is requested
+            to switch over to the official functions.</para>
+
+            <para>More recent versions of perl (e.g. 5.6.1 or higher)
+            support special flags to disinguish between UTF-8 and so
+            called binary data. XML::LibXML provides for these
+            versions functionality to make efficient use of these
+            flags: If a document has set an encoding other than UTF-8
+            all strings that are not already in UTF-8 are implicitly
+            encoded from the document encoding to UTF-8. On output
+            these strings are commonly returned as UTF-8 unless a user
+            does request explicitly the original (aka. document)
+            encoding.</para>
+
+            <para>Older version of perl (such as 5.00503 or less) do
+            not support these flags. If XML::LibXML is build for these
+            versions, all strings have to get encoded to UTF-8 manualy
+            before they are passed to any DOM functions.</para>
+
+            <para><emphasis>NOTE:</emphasis> XML::LibXML's magic
+            encoding may not work on all plattforms. Some platforms
+            are known to have a broken iconv(), which is partly used
+            by libxml2. To test if your platform works correctly with
+            your language encoding, build a simple document in the
+            particular encoding and try to parse it with
+            XML::LibXML. If your document gets parsed with out causing
+            any segmentation faults, bus errors or whatever your OS
+            throws. An example for such a test can be found in test
+            19encoding.t of the distribution.</para>
 
             <para><emphasis>Namespaces and XML::LibXML's DOM implementation</emphasis></para>
 
-            <para>XML::LibXML's DOM implementation follows the DOM implementation of libxml2. This is important to know if namespaces are used. Namespaces
-            cannot be declared on an document node. This is basicly because XPath doesn't know about document nodes. Therefore namespaces have to be
-            declared on element nodes. This can happen explicitly by using XML::LibXML:Element's setNamespace() function or more or less implicitly by using
-            XML::LibXML::Document's createElementNS() or createAttributeNS() function. If the a namespace is not declared on the documentElement, the
-            namespace will be localy declared for the newly created node. In case of Attributes this may look a bit confusing, since these nodes cannot have
-            namespace declarations itself. In this case the namespace in internally applied to the attribute and later declared on the node the attribute is
-            appended to.</para>
-
+            <para>XML::LibXML's DOM implementation is 
+            limitted by the DOM implementation of libxml2
+            which treats namespaces slightly differently than
+            required by the DOM Layer 2 specification.
+            </para>
+            <para>According to the DOM Layer 2 specification,
+             namespaces of elements and attributes should be
+             persistent, and nodes should be permanently bound to
+             namespace URIs as they get created; it should be
+             possible to manipulate the special attributes used for
+             declaring XML namespaces just as other attributes
+             without affecting the namespaces of other nodes.
+             In DOM Layer 2, the application is responsible
+             for creating the special attributes consistently and/or for correct
+             serialization of the document.
+            </para>
+            <para>
+	     This is both unconvenient, causes problems in serialization
+	     of DOM to XML, and most importantly, seems almost impossible
+             to implement over libxml2.
+            </para>
+            <para>
+             In libxml2, namespace URI and prefix of a node is
+             provided by a pointer to a namespace declaration
+             (appearing as a special xmlns attribute in the XML
+             document). If the prefix or namespace URI of the
+             declaration changes, the prefix and namespace URI of all
+             nodes that point to it changes as well.  Moreover, in
+             contrast to DOM, a node (element or attribute) can only
+             be bound to a namespace URI if there is some namespace
+             declaration in the document to point to.
+            </para>
+            <para>
+             Therefore current DOM implementation in XML::LibXML tries
+             to treat namespace declarations in a compromise between
+             reason, common sense, limitations of libxml2, and the DOM
+             Layer 2 specification.
+            </para>
+            <para>In XML::LibXML, special attributes declaring XML namespaces
+	     are often created automatically, usually when
+	     a namespaced node is attached to a document
+             and no existing declaration of the namespace and prefix is in the
+             scope to be reused.
+             In this respect,
+	     XML::LibXML DOM implementation differs from the DOM
+             Layer 2 specification according to which special
+              attributes for declaring the appropriate XML namespaces
+              should not be added when a node with a namespace prefix
+              and namespace URI is created.
+            </para>
+            <para>
+             Namespace declarations are also created when
+             XML::LibXML::Document's
+             createElementNS() or createAttributeNS() function are used. If the
+             a namespace is not declared on the documentElement, the
+             namespace will be localy declared for the newly created
+             node. In case of Attributes this may look a bit confusing,
+	     since these nodes cannot have namespace declarations
+	     itself. In this case the namespace is internally applied
+	     to the attribute and later declared on the node the
+             attribute is appended to (if required).</para>
             <para>The following example may explain this a bit:</para>
-
             <programlisting> my $doc = XML::LibXML-&gt;createDocument;
  my $root = $doc-&gt;createElementNS( "", "foo" );
  $doc-&gt;setDocumentElement( $root );
             <programlisting> &lt;?xml version="1.0"?&gt;
  &lt;foo xmlns:bar="bar" bar:foo="test"/&gt;</programlisting>
 
-            <para>Note that the namespace is declared on the document element while the setAttributeNodeNS() call.</para>
-
-            <para>Here it is important to repeat the specification: While working with namespaces you should use the namespace aware functions instead of the
-            simplified versions. For example you should <emphasis>never</emphasis> use setAttributeNode() but setAttributeNodeNS().</para>
+            <para>The namespace is declared on the document element
+              during the setAttributeNodeNS() call.
+            </para>
+            <para>Namespaces can be also declared explicitly by the use of XML::LibXML:Element's setNamespace() function.
+	     Since 1.61, they can also be manipulated with functions
+             setNamespaceDeclPrefix() and setNamespaceDeclURI() (not available in DOM).
+	     Changing an URI or prefix of an existing namespace declaration
+             affects the namespace URI and prefix of all nodes which point to it
+             (that is the nodes in its scope).
+            </para>
+            <para>It is also important to repeat the specification:
+            While working with namespaces you should use the namespace
+            aware functions instead of the simplified versions. For
+            example you should <emphasis>never</emphasis> use
+            setAttribute() but setAttributeNS().</para>
         </sect1>
     </chapter>
 
                     <funcsynopsis>
                         <funcsynopsisinfo>$node-&gt;setAttributeNS( $nsURI, $aname, $avalue );</funcsynopsisinfo>
                     </funcsynopsis>
-
-                    <para>Namespaceversion of <function>setAttribute</function>.</para>
+                    <para>Namespace-aware version of <function>setAttribute</function>, where
+                       <function>$nsURI</function> is a namespace URI,
+	               <function>$aname</function> is a qualified name,
+                       and <function>$avalue</function> is the value.
+                       The namespace URI may be null (empty or undefined)
+                       in order to create an attribute which has no namespace.
+	            </para>
+	            <para>
+	               The current implementation differs from DOM in the following aspectse
+                    </para>
+	            <para>
+                       If an attribute with the same local name and namespace URI already exists
+                       on the element, but its prefix differs from the prefix of <function>$aname</function>, 
+                       then this function is supposed to change the prefix (regardless
+                       of namespace declarations and possible collisions).
+                       However, the current implementation does rather the opposite.
+                       If a prefix is declared for the namespace URI in the scope
+                       of the attribute, then the already declared prefix is used,
+	               disregarding the prefix specified in <function>$aname</function>.
+                       If no prefix is declared for the namespace, the function tries
+                       to declare the prefix specified in <function>$aname</function>
+                       and dies if the prefix is already taken by some other namespace.
+	            </para>
+                    <para>According to DOM Layer 2 specification, this method can also be used to
+	              create or modify special attributes used for declaring XML namespaces
+	              (which belong to the namespace "http://www.w3.org/2000/xmlns/" and
+	              have prefix or name "xmlns"). This should work since version 1.61,
+	              but again the implementation differs from DOM specification in the following:
+                      if a declaration of the same namespace prefix already exists
+                      on the element, then changing its value via this method
+                      automatically changes the namespace of all elements and attributes
+                      in its scope. This is because in libxml2 the namespace URI of an element
+                      is not static but is computed from a pointer to a namespace declaration attribute.
+                    </para>
                 </listitem>
             </varlistentry>
         
                     this parameter is set to FALSE (0), the namespace
                     is simply added to the namespacelist of the node,
                     while the element's namespace itself is not
-                    altered. Nevertheless activate is set to TRUE (1)
+                    altered. Nevertheless, activate is set to TRUE (1)
                     on default. In this case the namespace
                     automatically is used as the nodes effective
                     namespace. This means the namespace prefix is
                     <programlisting> &lt;bar xmlns:foo="http://foobar.org"/&gt;</programlisting>
 
                     <para>By using $activate == 0 it is possible to
-                    apply multiple namepace declarations to a single
+                    create multiple namepace declarations on a single
                     element.</para>
-
-                    <para>Alternativly you can call setAttribute()
-                    simply to declare a new namespace for a node,
-                    without activating it:</para>
-
-                    <programlisting>  $e2-&gt;setAttribute( "xmlns:foo", "http://bar.org" );</programlisting>
-
-                    <para>has the same result as</para>
-
-                    <programlisting> $e2-&gt;setNamespace( "http://foobar.org", "foo", 0 );</programlisting>
                 </listitem>
             </varlistentry>
             <varlistentry>
 
                 <listitem>
                     <funcsynopsis>
-                        <funcsynopsisinfo>$known_prefix = $ns-&gt;getPredix();</funcsynopsisinfo>
+                        <funcsynopsisinfo>$known_prefix = $ns-&gt;getPrefix();</funcsynopsisinfo>
                     </funcsynopsis>
 
                     <para>Returns the string "xmlns"</para>

File lib/XML/LibXML/Boolean.pm

 use XML::LibXML::Literal;
 use strict;
 
+use vars qw ($VERSION);
+
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+
 use overload
         '""' => \&value,
         '<=>' => \&cmp;

File lib/XML/LibXML/Literal.pm

 use XML::LibXML::Number;
 use strict;
 
+use vars qw ($VERSION);
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+
 use overload 
 		'""' => \&value,
 		'cmp' => \&cmp;

File lib/XML/LibXML/NodeList.pm

 use XML::LibXML::Literal;
 use XML::LibXML::Number;
 
+use vars qw ($VERSION);
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+
 use overload 
 		'""' => \&to_literal,
                 'bool' => \&to_boolean,

File lib/XML/LibXML/Number.pm

 use XML::LibXML::Literal;
 use strict;
 
+use vars qw ($VERSION);
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+
 use overload
         '""' => \&value,
         '0+' => \&value,

File lib/XML/LibXML/SAX.pm

 use strict;
 use vars qw($VERSION @ISA);
 
-$VERSION = '1.00';
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
 
 use XML::LibXML;
 use XML::SAX::Base;

File lib/XML/LibXML/SAX/Builder.pm

 use XML::LibXML;
 use XML::NamespaceSupport;
 
+use vars qw ($VERSION);
+
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
+
 sub new {
     my $class = shift;
     return bless {@_}, $class;

File lib/XML/LibXML/SAX/Generator.pm

 use strict;
 
 use XML::LibXML;
+use vars qw ($VERSION);
+
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
 
 warn("This class (", __PACKAGE__, ") is deprecated!");
 

File lib/XML/LibXML/SAX/Parser.pm

 use XML::SAX::Base;
 use XML::SAX::DocumentLocator;
 
-$VERSION = '1.50';
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
 @ISA = ('XML::SAX::Base');
 
 sub _parse_characterstream {

File lib/XML/LibXML/XPathContext.pm

 use XML::LibXML;
 use XML::LibXML::NodeList;
 
-$VERSION = $XML::LibXML::VERSION;
+$VERSION = "1.61"; # VERSION TEMPLATE: DO NOT CHANGE
 
 # should LibXML XPath data types be used for simple objects
 # when passing parameters to extension functions (default: no)
 # -*- cperl -*-
 use Test;
-BEGIN { plan tests=>103; }
+BEGIN { plan tests=>104; }
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
 
 
 print "# 8. changing namespace declarations\n";
 {
+  my $xmlns = 'http://www.w3.org/2000/xmlns/';
+
     my $doc = XML::LibXML->createDocument; 
     my $root = $doc->createElementNS('http://example.com', 'document');
-    $root->setAttribute('xmlns:xxx', 'http://example.com');
+    $root->setAttributeNS($xmlns, 'xmlns:xxx', 'http://example.com');
     $root->setAttribute('xmlns:yyy', 'http://yonder.com');
     $doc->setDocumentElement( $root );
 
     # can we get the namespaces ?
     ok ( $root->getAttribute('xmlns:xxx'), 'http://example.com');
-    ok ( $root->getAttribute('xmlns'), 'http://example.com' );
+    ok ( $root->getAttributeNS($xmlns,'xmlns'), 'http://example.com' );
     ok ( $root->getAttribute('xmlns:yyy'), 'http://yonder.com');
     ok ( $root->lookupNamespacePrefix('http://yonder.com'), 'yyy');
     ok ( $root->lookupNamespaceURI('yyy'), 'http://yonder.com');
 
     # can we change the namespaces ?
-    $root->setAttribute('xmlns:yyy', 'http://newyonder.com');
+    ok ( $root->setAttribute('xmlns:yyy', 'http://newyonder.com') );
     ok ( $root->getAttribute('xmlns:yyy'), 'http://newyonder.com');
     ok ( $root->lookupNamespacePrefix('http://newyonder.com'), 'yyy');
     ok ( $root->lookupNamespaceURI('yyy'), 'http://newyonder.com');