Commits

garfieldnate  committed ce7af68

Created unique_key method

  • Participants
  • Parent commits e9257dc

Comments (0)

Files changed (5)

 Revision history for Perl extension XML::LibXML
 
+    - Added unique_key
+
 2.0019          Mon  1 Jul 11:04:31 IDT 2013
     - Correct typos reported in RT #86599.
         - https://rt.cpan.org/Ticket/Display.html?id=86599
 #include "xpath.h"
 #include "xpathcontext.h"
 
+/* unique_key stuff */
+#include "stdint.h"
+/*1 per bit in intptr_t, + 1 for trailing 0*/
+#define KEY_SIZE sizeof(intptr_t)+1
+
 #ifdef __cplusplus
 }
 #endif
     OUTPUT:
         RETVAL
 
+char*
+unique_key( self )
+        xmlNodePtr self
+    CODE:
+        /* Convert the node address into a hex string */
+        char hex_string[KEY_SIZE];
+        intptr_t address = (intptr_t) self;
+        sprintf(hex_string, "%0x", address);
+        hex_string[KEY_SIZE-1] = 0;
+        RETVAL = hex_string;
+    OUTPUT:
+        RETVAL
+
 SV *
 baseURI( self )
         xmlNodePtr self
 t/72destruction.t
 t/80registryleak.t
 t/90threads.t
+t/91unique_key.t
 t/data/callbacks_returning_undef.xml
 t/lib/Collector.pm
 t/lib/Counter.pm

File docs/libxml.dbk

 
 
             <varlistentry>
+                <term>unique_key</term>
+
+                <listitem>
+                    <funcsynopsis>
+                        <funcsynopsisinfo>$string = $node-&gt;unique_key;</funcsynopsisinfo>
+                    </funcsynopsis>
+
+                    <para>This function is not specified for any DOM level. It returns a key guaranteed to be unique for this node, and to always be the same value for this node. In other words, two node objects return the same key if and only if isSameNode indicates that they are the same node.</para>
+
+                    <para>The returned key value is useful as a key in hashes.</para>
+                </listitem>
+            </varlistentry>
+
+
+
+            <varlistentry>
                 <term>nodeValue</term>
 
                 <listitem>

File t/91unique_key.t

+# -*- cperl -*-
+# $Id$
+
+##
+# This test checks that unique_key works correctly.
+# it relies on the success of t/01basic.t, t/02parse.t, and t/04node.t
+
+use Test::More tests => 26;
+
+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();
+my $doc    = $parser->parse_string( $xmlstring );
+
+my $foo = $doc->documentElement;
+
+# TEST:$num_children=5;
+my @children_1 = $foo->childNodes;
+my @children_2 = $foo->childNodes;
+
+ok($children_1[0]->can('unique_key'), 'unique_key method available')
+    or exit -1;
+
+# compare unique keys between all nodes in the above tiny document.
+# Different nodes should have different keys; same nodes should have the same keys.
+for my $c1(0..4){
+    for my $c2(0..4){
+        if($c1 == $c2){
+            # TEST*$num_children
+            ok($children_1[$c1]->unique_key eq $children_2[$c2]->unique_key,
+                'Key for ' . $children_1[$c1]->nodeName .
+                ' matches key from same node');
+        }else{
+            # TEST*($num_children)*($num_children-1)
+            ok($children_1[$c1]->unique_key ne $children_2[$c2]->unique_key,
+                'Key for ' . $children_1[$c1]->nodeName .
+                ' does not match key for' . $children_2[$c2]->nodeName);
+        }
+    }
+}