Hi Berin,
> 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.
Any extension function used in Xalan's XPath implementation must have a
non-null namespace URI. The null namespace is used for built-in functions,
and I don't think it's a good idea to assume that an implementation will
allow for the addition of built-in functions. In fact, the XPath
recommendation says _nothing_ about extension functions, since it was
designed to be used by other specifications:
http://www.w3.org/TR/xpath#section-Conformance
This should be explicit in the XML Digital Signature recommendation. If
not, it ought to be.
> 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.
Xalan's XPath engine was specifically designed to support XSLT, so we
follow the XSLT recommendation when it comes to extension functions:
http://www.w3.org/TR/xslt#section-Extension-Functions
> 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".
Exactly. That's our view of XSLT conformance. We used to allow functions
to be installed as XPath functions, but it caused inefficiencies in the
implementation of the function table and allows for non-portable behavior.
> 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?
Whether or not the DSIG is broken and Xalan is correct is debatable. They
could both be valid interpretations of the recommendation. However, since
there's a reasonable mechanism for extensions (using functions with QName
instead of NCNames), why not follow it? As most major XPath engines were
written to support XSLT, it's the more portable way of doing it.
There's no way in the current code to install extension functions with a
null namespace URI and to allow it you'd have to make some fairly intrusive
changes. I think the DSIG recommendation ought to be changed.
> 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.
I've debated many about doing that. The problem is that when someone
accidently hands you a XalanNode-derived instance that's not really a
wrapper node, the cast is bad and results in undefined behavior. One
answer would be to use RTTI on the platforms that support it, which would
make it safe. That's probably the best bet, and the one to go with for the
release. Does that seem reasonable to you?
> Or is the reason for two maps that you want the WrapperNavigator not to
> make any assumptions about the underlying implementation of the
XercesNode?
It's mostly the safety issue, but fewer assumptions are always better!
Dave