If you want to use ElementPrefixResolverProxy, then you need to pass a
XalanElement node instance that has a namespace declaration in scope for
the prefix. Usually, ElementPrefixResolverProxy is only useful for
prefixes which are declared on the document element.
Your best bet is to implement a configurable prefix resolver. That way,
you can add the prefix/URI pairs you need. Of course, you could also
search the document for the Element that has the Namespace node you're
looking for:
"//namespace::A/parent*"
but then you'd have a problem if you found more than one.
This might be a useful class for including with Xalan, although I hesitate
to just implement things and throw them in, as then Xalan becomes
"everything but the kitchen sink."
Here's a possible implementation (not tested):
#include <map>
#include "PlatformSupport/DOMStringHelper.hpp"
#include "PlatformSupport/PrefixResolver.hpp"
class ConfigurablePrefixResolver : public PrefixResolver
{
public:
ConfigurablePrefixResolver() :
PrefixResolver(),
m_map(),
m_uri()
{
}
virtual
~ConfigurablePrefixResolver()
{
}
virtual const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString& prefix) const
{
const MapType::const_iterator i = m_map.find(prefix);
return i == m_map.end() ? 0 : &(*i).second;
}
virtual const XalanDOMString&
getURI() const
{
return m_uri;
}
void
setPrefix(
const XalanDOMString& prefix,
const XalanDOMString& uri)
{
m_map[prefix] = uri;
}
void
removePrefix(const XalanDOMString& prefix)
{
m_map.erase(prefix);
}
void
setURI(const XalanDOMString& uri)
{
m_uri = uri;
}
#if defined(XALAN_NO_NAMESPACES)
typedef map<XalanDOMString, XalanDOMString,
less<XalanDOMString> > MapType;
#else
typedef std::map<XalanDOMString, XalanDOMString> MapType;
#endif
private:
MapType m_map;
XalanDOMString m_uri;
};
Dave
"Gaur, Manish"
<[EMAIL PROTECTED] To: "Xalan List (E-mail)"
<[email protected]>
ty.COM> cc: (bcc: David N
Bertoni/Cambridge/IBM)
Subject: A PerfixResolver
Question
07/30/2002 12:33
AM
Hi,
If I were to evaluate the expression "not(ancestor-or-self::A:Signature)"
on the following input Document, the result should be all nodes
except the Signature node.
<DocumentRoot>
<ManyNodes1>
</ManyNodes1>
<A:Signature xmlns:A="someuri"/>
<ManyNodes1>
</ManyNodes1>
<ManyNodes1>
</ManyNodes1>
</DocumentRoot>
This is what I am doing,
//..(decls and inits)
const char *expression = "not(ancestor-or-self::A:Signature)" ;
// select all nodes
const XObjectPtr theResult(
theEvaluator.evaluate(
theDOMSupport,
theDocument,
XalanDOMString("(/descendant-or-self::node()/.|//@*|//namespace::*)").
c_str(
))) ;
// for each node evaluate expression
for (NodeRefList::size_type j = 0; j < (theResult->nodeset()).getLength();
++j)
{
XalanNode *thisNode = (theResult->nodeset()).item(j) ;
XPathEvaluator objEvaluator ;
// evaluate expression on node
const XObjectPtr objPointer(
objEvaluator.evaluate(
theDOMSupport,
thisNode,
XalanDOMString(expression).c_str(),
ElementPrefixResolverProxy(
theDocument->getDocumentElement(),
XPathEnvSupportDefault(),
theDOMSupport))) ;
if(objPointer->boolean())
// do something
}
As you notice, I am using ElementPrefixResolverProxy and initializing
the namespaceContext as the documentElement.
Ofcourse, this fails with an XSLException on the first node in the nodelist
itself (which is the document root node), as it doesn't know about the
xmlns:A namespace yet so it cannot resolve it.
My question is, what is the right namespaceContext for
expressions (and documents) like these??
or am I missing something fundamental here?
Your help is greatly appreciated.
Regards,
/Manish
PS: Sorry for such a long message. Please feel free to ask for
clarifications.