David,

Worked a treat. Now an apology for the length of the rest of this message, but it's difficult to describe the two issues without giving some background.

External Functions
------------------------

Part of the XML Digital Signature spec (which is basically what I'm playing with - people do strange things in their spare time) defines a function here(), which is a function that returns the Node where the XPath expression was defined.

One of the common ways of using this is to do things like :

"count(ancestor-or-self::dsig:Signature |
here()/ancestor::dsig:Signature[1]) >
count(ancestor-or-self::dsig:Signature)"

as a true/false test to see whether the node in question is inside the Signature where the XPath was defined.

As you can see - the here() does not have a namespace prefix - and many of the signatures floating around in the interoperability tests use the form above.

Previously this wasn't a problem - I was inadvertantly inserting the external function in the local functions table. This would have caused me LARGE problems down the track (only one instance for all threads), but ignorance is bliss.

It is now causing an Exception when I initialise the XPath (after I have loaded the external function with a dummy namespace). Going through the code, my reading is that Xalan says that "If you don't have a namespace prefix, you are not an external function and here() is not defined in the XPath spec, therefore it cannot be local".

I have two options. I can parse the expression before they hit Xalan and add a dummy namespace and prefix, or I can mod Xalan to work with local functions that use a "" namespace.

If the DSIG spec is incorrect I will do the former. If Xalan should allow this, I will do the latter and put the mods in bugzilla unless you would prefer to look at it. My only question would be is it OK for me to define a dummy namespace to use as a key to the map container?

mapNode
------------

The suggested mod worked beautifully. Do you want me to play with the createDocument interfaces to allow people to request node mappings?

One question though - is there a need for both maps? Might it be possible to make XercesWrapperNavigator a friend class to all the wrapper classes and then pull the m_xercesNode directly from the XalanNode *? This would allow one way mapping (from Xalan back to Xerces) which might suffice for most requirements (it certainly would for mine). If people wanted both, then they could request the map for xerces->xalan also be built.

Or is the reason for two maps that you want the WrapperNavigator not to make any assumptions about the underlying implementation of the XercesNode?

Cheers,
   Berin



David N Bertoni/Cambridge/IBM wrote:



Hi Berin,

You're probably working in the mode were the wrapper is "pre-built," which
yields reasonable performance, but doesn't allow mapping from a Xerces node
to a Xalan node.  The assumption is that you really wouldn't want to do
that since you already have Xalan nodes returned by the execution of the
XPath expression.

I think there was another request for this feature, so I'm pretty sure I
can make it an option.  If you want to experiment, I suggest you modify the
wrapper layer yourself.  Try this patch and see what happens:

  cvs -z9 diff XercesDocumentWrapper.cpp (in directory
  V:\xml-xalan\c\src\XercesParserLiaison\)
  Index: XercesDocumentWrapper.cpp
  ===================================================================
  RCS file:
  /home/cvs/xml-xalan/c/src/XercesParserLiaison/XercesDocumentWrapper.cpp,v
  retrieving revision 1.3
  diff -r1.3 XercesDocumentWrapper.cpp
  692a693,694
  >  mapNode = true;
  >

  *****CVS exited normally with code 1*****

The reason for avoiding the map is it consumes huge amounts of memory  (we
really need to use a hash table instead of a map).

Dave



Berin Lautenbach <[EMAIL PROTECTED] To: Xalan C Users <[email protected]> om.au> cc: (bcc: David N Bertoni/Cambridge/IBM) Subject: Re: Latest CVS 11/15/2002 01:19 PM



David,

Felt a bit of a dill last night - worked this out and (as I am using
XPath directly) am installing the functions into the
XPathEnvSupportDefault.

Only problem is I cannot seem to map nodes to and from Xerces<->Xalan.

The XPath is working properly, but when I use
theWrapperNavigator->mapNode(theXercesNode) I get back a NULL pointer.

When I go the opposite way (from a xalanNode fount in a nodelist return
item()) I get an exception.

But the mapping is working, because the XPath->exexcute(....) is finding
a number of nodes that looks to be about right.

I also know the xercesNode I want to find the xalanNode for was mapped,
because I have whatched the build treewalker find the node.  (My problem
is once it gets inside the STL map it gets tricky to track.)

So I was wondering - is there anything I need to do to make this work?

I haven't got the source in front of me, but from memory I use a
xercesParserLiason->getDocument to get a document, and I then use the
ParserLiason to get a wrapper from which I build a wrapperNavigator.  Is
there something important I have missed?

Cheers,
   Berin

David N Bertoni/Cambridge/IBM wrote:



<[EMAIL PROTECTED]> wrote:




I am converting some code over to the "new" DOM implementation in Xerces,
so last night downloaded the latest (at that time) CVS tarball.

Always a dangerous thing to do.....




Livin' on the edge is fun!





Worked out how to move to the new *Wrapper classes, and had a whole lot




of fun




and then came up with two questions.




I hope it's working. It really does need more testing, and probably needs
some more features added that were in the previous bridge.





Firstly - I notice that the wrappers treat DOMNode pointers as const.




Makes




sense, but means that if I want to edit a returned node (e.g. from an




XPath




selection) then I need to cast the return.  Was there a reason for moving




to




const (other than the obvious of it being a cleaner programming model for




the




library)?




Well, there's wasn't much point in const with the old smart-pointer DOM,


so


this is the first time const made any sense.  The reason is we try to stay
const-correct within the engine, since XSLT doesn't allow modification of
the source tree.  Casting-off const shouldn't be any problem, so I felt it
best to leave that to the user.  It also helps insure we don't
inadvertantly modify the underlying Xerces DOM, which would not be good.





Secondly - I install an additional XPath function, which now causes an




exception.




Being curious I went through the code and realised the function table is




in the middle




of being re-written (as I said - working from CVS code is always




dangerous).

Actually, it's finished being re-written.  The new code enforces the
content of the standard function table.  We're no longer going to support
installing functions into the standard table -- you should install them in
the proper place.  See the ExtensionFunction sample for more information.





I have a function that is context sensitive (the "here()" function




defined in XML
Signature).  The easiest way to do this function is install an instance
with the




appropriate node hard-coded and then un-install when the XPath selection




is done.




This is fine under a static table until you hit multiple threads, at




which point things




could get interesting.  Different threads might want to install slightly




different versions




of the same function at any given time.




That's why there are per-instance functions tables.  See
XalanTransformer::installFunctionLocal() and
XalanTransformer::installFunctionGlobal().

Dave


















Reply via email to