1. Shlomi Fish
  2. perl-XML-LibXML

Commits

pa...@9ae0c189-cd1f-4510-a509-f4891f5cf20d  committed f54ed6f

added support for exclusive canonicalization of XML (http://www.w3.org/TR/xml-exc-c14n/)

  • Participants
  • Parent commits a961aa5
  • Branches default

Comments (0)

Files changed (7)

File Changes

View file
 
 post 1.63
    - added no_network parser flag
+   - added support for exclusive canonicalization (http://www.w3.org/TR/xml-exc-c14n/)
    - make XInclude reflect parser flags
    - documentation fixes
  

File LibXML.pm

View file
     $doc->adoptNode( $self );
 }
 
-sub serialize_c14n {
-    my $self = shift;
-    return $self->toStringC14N( @_ );
+sub toStringC14N {
+    my ($self, $comments, $xpath) = (shift, shift, shift);
+    return $self->_toStringC14N( $comments || 0,
+				 (defined $xpath ? $xpath : undef),
+				 0,
+				 undef );
 }
+sub toStringEC14N {
+    my ($self, $comments, $xpath, $inc_prefix_list) = @_;
+    if (defined($inc_prefix_list) and !UNIVERSAL::isa($inc_prefix_list,'ARRAY')) {
+      croak("toStringEC14N: inclusive_prefix_list must be undefined or ARRAY");
+    }
+    return $self->_toStringC14N( $comments || 0,
+				 (defined $xpath ? $xpath : undef),
+				 1,
+				 (defined $inc_prefix_list ? $inc_prefix_list : undef));
+}
+
+*serialize_c14n = \&toStringC14N;
+*serialize_exc_c14n = \&toStringEC14N;
 
 1;
 

File LibXML.xs

View file
 #include "perl.h"
 #include "XSUB.h"
 #include "ppport.h"
+#include "Av_CharPtrPtr.h"  /* XS_*_charPtrPtr() */
 
 #include <fcntl.h>
 
 	if( NULL == saved_error ) {
 		SV * sv = sv_2mortal(newSV(0));
 		va_start(args, msg);
+                /* vfprintf(stderr, msg, args); */
    		sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL);
    		va_end(args);
 		croak("%s", SvPV_nolen(sv));
 	/* Otherwise, save the error */
 	} else {
 		va_start(args, msg);
+                /* vfprintf(stderr, msg, args);	*/
    		sv_vcatpvfn(saved_error, msg, strlen(msg), &args, NULL, 0, NULL);
 		va_end(args);
 	}
 
 
 SV *
-toStringC14N(self, comments=0, xpath = &PL_sv_undef)
+_toStringC14N(self, comments=0, xpath=&PL_sv_undef, exclusive=0, inc_prefix_list=NULL)
         xmlNodePtr self
         int comments
         SV * xpath
+        int exclusive
+        char** inc_prefix_list
+
     PREINIT:
         SV * saved_error = sv_2mortal(newSVpv("",0));
         xmlChar *result               = NULL;
 
         xmlC14NDocDumpMemory( self->doc,
                               nodelist,
-                              0, NULL,
+                              exclusive, inc_prefix_list,
                               comments,
                               &result );
 
                                   (xmlRelaxNGValidityErrorFunc)LibXML_error_handler_ctx,
                                   (xmlRelaxNGValidityWarningFunc)LibXML_error_handler_ctx,
                                   saved_error );
-
+	/* ** test only **
+          xmlRelaxNGSetValidErrors( vctxt,
+                                    (xmlRelaxNGValidityErrorFunc)fprintf,
+                                    (xmlRelaxNGValidityWarningFunc)fprintf,
+                                    stderr );
+	*/
         RETVAL = xmlRelaxNGValidateDoc( vctxt, doc );
         xmlRelaxNGFreeValidCtxt( vctxt );
 

File MANIFEST

View file
 perl-libxml-mm.h
 perl-libxml-sax.c
 perl-libxml-sax.h
+Av_CharPtrPtr.c
+Av_CharPtrPtr.h
 typemap
 docs/libxml.dbk
 example/article_bad.xml
 lib/XML/LibXML/Reader.pm
 t/40reader.t
 test/textReader/countries.xml
-

File README

View file
 These packages are required. If one is missing some tests will fail.
 
 Again, libxml2 is required to make XML::LibXML work. The library is not just
-requiered to build XML::LibXML, it has to be accessible during runtime as well.
+required to build XML::LibXML, it has to be accessible during run-time as well.
 Because of this you need to make sure libxml2 is installed properly. To test
 this, run the xmllint program on your system. xmllint is shipped with libxml2
 and therefore should be available. For building the module you will also need
 Notes on libxml2 versions
 =========================
 
-XML::LibXML requires at least libxml2 2.6.16 to compile and pass all tests. For
-some older OS versions this means that an update of the prebuild packages is
-required.
+XML::LibXML requires at least libxml2 2.6.16 to compile and pass all tests and
+at least 2.6.21 is required for XML::LibXML::Reader. For some older OS versions
+this means that an update of the pre-built packages is required.
 
 Although libxml2 claims binary compatibility between its patch levels, it is a
 good idea to recompile XML::LibXML and XML::LibXML::Common and run its tests
 will ask '/usr/brand-new/bin/xml2-config' about your real libxml2
 configuration.
 
-Try to avoid setting INC and LIBS directly on the commandline, for if used,
+Try to avoid setting INC and LIBS directly on the command-line, for if used,
 Makefile.PL does not check the libxml2 version for compatibility with
 XML::LibXML.
 
 
 If Makefile.PL detects one of the incompatible versions, it notifies the user.
 It may still happen that XML::LibXML builds and pass its tests with such a
-version, but that does not mean everything is ok. There will be no support at
+version, but that does not mean everything is OK. There will be no support at
 all for blacklisted versions!
 
 As of XML::LibXML 1.61, only versions 2.6.16 and higher are supported.
 Notes for Microsoft Windows
 ===========================
 
-Thanks to Randy Kobes there is a precompiled PPM package available on
+Thanks to Randy Kobes there is a pre-compiled PPM package available on
 
 http://theoryx5.uwinnipeg.ca/ppmpackages/
 
 Due refactoring the module, XML::LibXML will not run with some earlier versions
 of Mac OS X. It appears that this is related to special linker options for that
 OS prior to version 10.2.2. Since the developers do not have full access to
-this OS, help/ patches from OS X gurus are highly apprecheated.
+this OS, help/ patches from OS X gurus are highly appreciated.
 
 It is confirmed that XML::LibXML builds and runs without problems since Mac OS
 X 10.2.6.
 Please consider all regression tests as correct. If any test fails it is most
 certainly related to a bug.
 
-If you find documentation bugs, please fix them in the libxml.dkb file, stored
+If you find documentation bugs, please fix them in the libxml.dbk file, stored
 in the docs directory.
 
 

File docs/libxml.dbk

View file
                 <term>toStringC14N</term>
 
                 <listitem>
-                    <para><funcsynopsis><funcsynopsisinfo>$c14nstr = $doc-&gt;toStringC14N($comment_flag,$xpath); </funcsynopsisinfo></funcsynopsis> A variation
-                    to toString, that returns the canonized form of the given document.</para>
+                    <para><funcsynopsis><funcsynopsisinfo>$c14nstr = $doc-&gt;toStringC14N($comment_flag,$xpath); </funcsynopsisinfo></funcsynopsis>
+	            See the documentation in XML::LibXML::Node.
+                    </para>
                 </listitem>
             </varlistentry>
-
+            <varlistentry>
+                <term>toStringEC14N</term>
+
+                <listitem>
+                    <para><funcsynopsis><funcsynopsisinfo>$ec14nstr = $doc-&gt;toStringEC14N($inclusive_prefix_list, $comment_flag,$xpath); </funcsynopsisinfo></funcsynopsis>
+	            See the documentation in XML::LibXML::Node.
+                   </para>
+                </listitem>
+            </varlistentry>
             <varlistentry>
                 <term>serialize</term>
 
                     <para>An alias for toStringC14N().</para>
                 </listitem>
             </varlistentry>
+            <varlistentry>
+                <term>serialize_exc_c14n</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$ec14nstr = $doc-&gt;serialize_exc_c14n($comment_flag,$xpath,$inclusive_prefix_list); </funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>An alias for toStringEC14N().</para>
+                </listitem>
+            </varlistentry>
 
             <varlistentry>
                 <term>toFile</term>
                     </funcsynopsis>
 
                     <para>The function is similar to toString(). Instead of simply serializing the document tree, it transforms it as it is specified in the
-                    XML-C14N Specification. Such transformation is known as canonization.</para>
+                    XML-C14N Specification (see <ulink url="http://www.w3.org/TR/xml-c14n">http://www.w3.org/TR/xml-c14n</ulink>). 
+                    Such transformation is known as canonization.</para>
 
                     <para>If $with_comments is 0 or not defined, the result-document will not contain any comments that exist in the original document. To
                     include comments into the canonized document, $with_comments has to be set to 1.</para>
                     child-nodes will not exist in the resulting document, unless they are part of the nodeset defined by the xpath expression.</para>
 
                     <para>If $xpath_expression is omitted or empty, toStringC14N() will include all nodes in the given sub-tree.</para>
-
-                    <para>No serializing flags will be recognized by this function!</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>toStringEC14N</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$ec14nstring = $node-&gt;toStringEC14N($with_comments, $xpath_expression, $inclusive_prefix_list);</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>The function is similar to toStringC14N() but follows
+                    the XML-EXC-C14N Specification (see <ulink url="http://www.w3.org/TR/xml-exc-c14n">http://www.w3.org/TR/xml-exc-c14n</ulink>)
+	            for exclusive canonization of XML.</para>
+
+                    <para>The first two arguments are as above. If $inclusive_prefix_list is
+	              used, it should be an ARRAY reference listing 
+                      namespace prefixes that are to be handled in the manner described by the Canonical XML Recommendation (i.e. preserved in the output even if the namespace is not used). C.f. the spec for details.
+	            </para>
                 </listitem>
             </varlistentry>
 
                     <para>An alias for toStringC14N().</para>
                 </listitem>
             </varlistentry>
+            <varlistentry>
+                <term>serialize_exc_c14n</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$ec14nstr = $doc-&gt;serialize_ec14n($comment_flag,$xpath,$inclusive_prefix_list); </funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>An alias for toStringEC14N().</para>
+                </listitem>
+            </varlistentry>
         
 
         

File t/24c14n.t

View file
+# -*- cperl -*-
 # $Id$
 
 ##
 use Test;
 use strict;
 
-BEGIN { plan tests => 14 };
+BEGIN { plan tests => 20 };
 use XML::LibXML;
 use XML::LibXML::Common qw(:libxml);
 
     $c14n_res = $rootnode->toStringC14N(0);
     ok( $c14n_res, '<b xmlns="http://foo/test#"><c></c><d><e></e></d></b>' );
 }
+
+print "# exclusive canonicalization\n";
+
+{
+  my $xml1 = <<EOX;
+<n0:local xmlns:n0="http://something.org" xmlns:n3="ftp://example.org">
+  <n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
+     <n3:stuff xmlns:n3="ftp://example.org"/>
+  </n1:elem2>
+</n0:local>
+EOX
+
+  my $xml2 = <<EOX;
+<n2:pdu xmlns:n1="http://example.com"
+           xmlns:n2="http://foo.example"
+           xml:lang="fr"
+           xml:space="retain">
+  <n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
+     <n3:stuff xmlns:n3="ftp://example.org"/>
+  </n1:elem2>
+</n2:pdu>
+EOX
+    my $xpath = "(//. | //@* | //namespace::*)[ancestor-or-self::*[name()='n1:elem2']]";
+    my $result = qq(<n1:elem2 xmlns:n1="http://example.net" xml:lang="en">\n     <n3:stuff xmlns:n3="ftp://example.org"></n3:stuff>\n  </n1:elem2>);
+    my $result_n0n2 = qq(<n1:elem2 xmlns:n1="http://example.net" xmlns:n2="http://foo.example" xml:lang="en">\n     <n3:stuff xmlns:n3="ftp://example.org"></n3:stuff>\n  </n1:elem2>);
+  my $doc1 = $parser->parse_string( $xml1 );
+  my $doc2 = $parser->parse_string( $xml2 );
+
+  {
+    my $c14n_res = $doc1->toStringEC14N(0, $xpath);
+    ok( $c14n_res, $result);
+  }
+  {
+    my $c14n_res = $doc2->toStringEC14N(0, $xpath);
+    ok( $c14n_res, $result);
+  }
+  {
+    my $c14n_res = $doc1->toStringEC14N(0, $xpath,[]);
+    ok( $c14n_res, $result);
+  }
+  {
+    my $c14n_res = $doc2->toStringEC14N(0, $xpath,[]);
+    ok( $c14n_res, $result);
+  }
+  {
+    my $c14n_res = $doc2->toStringEC14N(0, $xpath,['n1','n3']);
+    ok( $c14n_res, $result);
+  }
+  {
+    my $c14n_res = $doc2->toStringEC14N(0, $xpath,['n0','n2']);
+    ok( $c14n_res, $result_n0n2);
+  }
+
+}