Hi,
I have a webapplication where I hold a large XML tree in memory. On
this tree
I perform several transforms as response to user requests.
Each transform declares a <xsl:key> that serves as an index for
important nodes in the tree.
However, it is expensive to calculate this key and it should be possible
to reuse it since I know that the source tree has not been modified.
Since modifying the Xalan <xsl:key> implementation is difficult, I tried
my luck with a
Java extension approach where I simply store selected nodes in a
HashMap outside
the transform.
However, when I return a node from the extension then Xalan goes boom!
if the node
was added in a previous transform.
Does anyone know how to make this work ?
Best regards
Christoffer Dam Bruun
// The Java extension
public class ElementIndex {
public static Map<String, SingleIndex> indexes = new HashMap<String,
SingleIndex>();
public static Node key(String indexId, String key) {
NodeSet ns = new NodeSet();
SingleIndex idx = indexes.get(indexId);
if (null == idx) {
System.err.println("idx er null");
}
List<Node> nl = idx.get(key);
if (null == nl) {
return null;
}
return nl.get(0);
}
public static int add(ExpressionContext ec, String indexId, String
key, NodeList nodes) {
SingleIndex idx = indexes.get(indexId);
if (null == idx) {
idx = new SingleIndex();
indexes.put(indexId, idx);
}
for (int i = 0; i < nodes.getLength(); i++) {
Node tmp = nodes.item(i);
idx.put(key, tmp);
}
return 0;
}
public static int remove(String indexId) {
return 0;
}
public static int clear(String indexId) {
return 0;
}
public static class SingleIndex {
String idxName;
Map<String, ArrayList<Node>> idx = new HashMap<String,
ArrayList<Node>>();
public List<Node> get(String key) {
return idx.get(key);
}
public void put(String key, Node n) {
List<Node> nl = idx.get(key);
if (null == nl) {
nl = new ArrayList<Node>();
idx.put(key, (ArrayList<Node>) nl);
}
nl.add(n);
}
public void remove(String key, Node n) {
List<Node> nl = idx.get(key);
if (null == nl) {
return;
}
nl.remove(n);
}
}
}
// Adding to the index:
<xsl:value-of select="idx:add('nidkey', @nid,current())"/>
// Getting nodes from the index
<xsl:variable name="task" select="idx:key('nidkey',@nid)"></xsl:variable>