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>





Reply via email to