One of the changes I've noticed with 1.5 is that my naughty dictionary
function is broken. This is a bad thing, because it's not XSLT like (i.e. not
strictly functional), but it's very handy.
Essentially it goes:
class FunctionDictionary : public Function
{
virtual XObjectPtr
execute(
XPathExecutionContext& executionContext,
XalanNode* /* context */,
const XObjectPtr arg1,
const XObjectPtr arg2,
const Locator* /* locator */) const
{
m_dic[arg1->str().data()] = arg2;
return arg2;
}
virtual XObjectPtr
execute(
XPathExecutionContext& executionContext,
XalanNode* /* context */,
const Locator* /* locator */) const
{
XPathExecutionContext::BorrowReturnMutableNodeRefList
theNodeList(executionContext);
for (dictionary_t::iterator it = m_dic.begin();
it != m_dic.end(); ++it) {
XalanNode* node =
(*it).second->rtree().getNodesetRoot();
theNodeList->addNode(node);
}
// turn the document into a node set
return
executionContext.getXObjectFactory().createNodeSet(theNodeList);
}
typedef std::map<std::wstring, XObjectPtr> dictionary_t;
mutable dictionary_t m_dic;
};
(There is also a corresponding single argument lookup method which isn't
interesting for this problem).
The XSLT does something like:
<xsl:template name="foobar">
<xsl:param name="id"/>
<xsl:variable name="a">
<node/>
</xsl:variable>
<xsl:variable name="q" select="gnomon:dictionary(concat('meep',$id),$a)"/>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="foobar"><xsl:with-param
name="id">1</xsl:with-param></xsl:call-template>
<xsl:call-template name="foobar"><xsl:with-param
name="id">2</xsl:with-param></xsl:call-template>
<xsl:copy-of select="gnomon:dictionary()/meep1"/>
</xsl:template>
Now it's OK with one invocation (just the call-template with id=1), but with
two invocations there is an assertion failure in
XalanSourceTreeDOMSupport::isNodeAfter:
assert(node1.isIndexed() == true && node2.isIndexed() == true);
The nodes are result tree fragments, which correspond to
XalanSourceTreeDocumentFragment, which return false in isIndexed().
Part of the problem here is that I have basically no idea what is going so some
explanation would be handy :) I believe the assumption is that the nodeset
contains nodes selected from the document (which isn't unreasonable, I'm
admittedly doing something really strange), so adding them in order would
appear to be a (new since 1.4) optimisation. Is that correct?
If so, is there something that I can do to solve this? (e.g. copy the nodes;
or copy the nodes to a different document -- the code appears to check when
attempting to order the nodes if they are from the same document, which makes
sense).
Thanks,
Mark