Howto implement a node index extension to be shared across transform invocations on the same source document (DOMSource)

Christoffer Dam Bruun <[email protected]>
Newsgroups gmane.text.xml.xalan.java.user
Message-ID <[email protected]>
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>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.