You are viewing a plain text version of this content. The canonical link for it is here.
Posted to p-dev@xerces.apache.org by Brian Thomas <th...@adc.gsfc.nasa.gov> on 2001/04/26 18:30:28 UTC

Subclassing Xerces-P (Was: Re: About XML::Xerces, bugs, observations and questions.)

On Friday 13 April 2001 01:37 pm, Jason E. Stewart wrote:
> "Jason E. Stewart" <ja...@openinformatics.com> writes:
> > "Brian Thomas" <th...@adc.gsfc.nasa.gov> writes:
> > >    However, I find that I need to be able to sub-class the
> > >    DOM::Element AND be able to insert it in the parent document
> > >    (which is holding an XML::Xerces::DOM_Document in a private
> > >    field). The parent document attempts to insert the sub-classed
> > >    element object, and then gets a failure statement. Something to
> > >    the effect of 'This is not a Xerces::DOM_Element you are trying
> > >    to insert here bud, forget it'.
> >
> > Hey Brian, I've looked into this a bit, and I now understand that I
> > don't understand enough about the issue so I guess I'll have to see a
> > little bit more detailed example of what you're attempting. Are you
> > doing the subclassing purely in Perl, or are you actually creating a
> > new subclass in C++? Are you using createElement() to create the
> > element that you're inserting?

	Hi Jason,

	Well, I've downloaded and compiled Xerces-1.4.0 with minimal
	problems. I still having problems sub-classing DOM_Element.
	As it turns out, I was already using your prescription for using
	the underlying C++ object (see attached files). As it turns out,
	I am still seeing that SWIG wont recognize the sub-classed element
	node, XDF::DOM::Element, which is sub-classed from XML::Xerces::DOM_Element.
	Here's the error reportage:

Got parser: XDF::DOM::Parser=HASH(0x80f86e0)
STORING XDF OBJECT UNDER SELF, key:XDF , XDF::Structure=HASH(0x898b664)
STORE gets XML::Xerces::DOM_Element=SCALAR(0x8402c1c):[XDF,XDF::Structure=HASH(0x898b664),]
Finished init
XDF::DOM::Element returning self: XDF::DOM::Element=HASH(0x81d1568)
parentNode:XML::Xerces::DOM_Element=HASH(0x818bf9c) appending Xdf child node: XDF::DOM::Element=HASH(0x81d1568)
Type error in argument 2 of DOM_Node_appendChild. Expected XML::Xerces::DOM_Node at /usr/lib/perl5/site_perl/5.6.0/i386-linux/XML/Xerces.pm line 1102.

	Im  not attaching it, but I also edited Xerces.pm to have STORE and FETCH methods,
	which as I previously mentioned, are also needed. The hacked in code looks like:

sub STORE {
  my $self = shift;
  print STDERR "STORE gets $self:[",join ',',@_,"]\n";
}

sub FETCH {
  my $self = shift;
  print STDERR "FETCH gets $self:[",join ',',@_,"]\n";
}

	I've not tried trying to see if added methods in the new class will work, however, the 'sub this'
	code looks unchanged still. If you have trouble running this example, I can probably
	whip up some test code if you like. Just let me know. 

						-b.t.

e:



> >
> > Also, once you get it into the DOM, is it important for the DOM to be
> > able to extract it as an XDF::Element as well?
>
> Hey Brian,
>
> After having dug around into Xerces.C and SWIG a bit more, I'm
> convinced that this should work (it works for stuff we've compiled
> into Xerces.C). The issue is that underneath whatever Perl Class
> you've implemented to deal with things, it needs to have a valid
> XML::Xerces::DOM_Element object.
>
> So in your XDF::Element::new() method, you'll need to invoke
> CreateElement().
>
> If you choose to subclass DOMParser into XDF::DOMParser, you could
> overload it's CreateElement() method to give you back an XDF::Element
> when necessary.
>
> Does this help?
> jas.

-- 

  * Brian Thomas 
  * ADC NASA/Raytheon ITSS

  *   fax: (301) 286-1771
  * phone: (301) 286-6128

Command, n.:
	Statement presented by a human and accepted by a computer in
	such a manner as to make the human feel as if he is in control.

Fixed! (was Re: Subclassing Xerces-P)

Posted by "Jason E. Stewart" <ja...@openinformatics.com>.
Hey Brian,

Just so you don't think I've died of a heart attack, or disappeared
off the face of the earth...

I stumbled into the same issue in a more roundabout way, and I dug
deeper into what SWIG was doing 'under the covers'. The problem lies
in the SWIG_TypeCheck function in Xerces.C. Instead of checking the
inheritance hierarchy as it could, the method just does straight
strcmp()'s against the static types it knows about. This is exactly
what you want if all your subclasses are defined in C++ ==> you don't
want the risk of dereferencing a bad pointer. But the whole point of
wrapping a module is to make it accessible from perl, including
defining subclasses.

The fix is to force SWIG_TypeCheck to call sv_derived_from() using an
SV* and not call strcmp() using a char*. So when SWIG_TypeCheck is
called from within SWIG_ConvertPtr it needs the SV*. I'm including a
patch to Xerces.C that should fix this problem. I will have it in the
next release (which will be next week).

Let me know if this works for you.
jas.


-- begin diff --
*** Xerces.C~	Mon May 14 15:28:59 2001
--- Xerces.C	Mon May 14 15:30:35 2001
***************
*** 107,138 ****
    return ret;
  }
  
- /* Check the typename */
- SWIGRUNTIME(swig_type_info *) 
- SWIG_TypeCheck(char *c, swig_type_info *ty)
- {
-   swig_type_info *s;
-   if (!ty) return 0;        /* Void pointer */
-   s = ty->next;             /* First element always just a name */
-   while (s) {
-     if (strcmp(s->name,c) == 0) {
-       if (s == ty->next) return s;
-       /* Move s to the top of the linked list */
-       s->prev->next = s->next;
-       if (s->next) {
- 	s->next->prev = s->prev;
-       }
-       /* Insert s as second element in the list */
-       s->next = ty->next;
-       if (ty->next) ty->next->prev = s;
-       ty->next = s;
-       return s;
-     }
-     s = s->next;
-   }
-   return 0;
- }
- 
  /* Cast a pointer (needed for C++ inheritance */
  SWIGRUNTIME(void *) 
  SWIG_TypeCast(swig_type_info *ty, void *ptr) 
--- 107,112 ----
***************
*** 190,195 ****
--- 164,197 ----
  }
  #endif
  
+ /* Check the typename */
+ SWIGRUNTIME(swig_type_info *) 
+ SWIG_TypeCheck(SV *sv, swig_type_info *ty)
+ {
+     printf("calling new type check\n");
+   swig_type_info *s;
+   if (!ty) return 0;        /* Void pointer */
+   s = ty->next;             /* First element always just a name */
+   while (s) {
+     if (sv_derived_from(sv,s->name)) {
+       if (s == ty->next) return s;
+       /* Move s to the top of the linked list */
+       s->prev->next = s->next;
+       if (s->next) {
+ 	s->next->prev = s->prev;
+       }
+       /* Insert s as second element in the list */
+       s->next = ty->next;
+       if (ty->next) ty->next->prev = s;
+       ty->next = s;
+       return s;
+     }
+     s = s->next;
+   }
+   return 0;
+ }
+ 
+ 
  #ifdef PERL_OBJECT
  #define MAGIC_PPERL  CPerlObj *pPerl = (CPerlObj *) this;
  #define MAGIC_CAST   (int (CPerlObj::*)(SV *, MAGIC *))
***************
*** 295,302 ****
    }
    if (_t) {
      /* Now see if the types match */      
!     _c = HvNAME(SvSTASH(SvRV(sv)));
!     tc = SWIG_TypeCheck(_c,_t);
      if (!tc) {
        *ptr = (void *) tmp;
        return -1;
--- 297,305 ----
    }
    if (_t) {
      /* Now see if the types match */      
! //    _c = HvNAME(SvSTASH(SvRV(sv))); 
!     tc = SWIG_TypeCheck(sv,_t);
! 
      if (!tc) {
        *ptr = (void *) tmp;
        return -1;

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org