You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by Evan Lenz <el...@xyzfind.com> on 2001/07/31 02:23:35 UTC

Performance problems when passing node-set as global XSLT parameter

I have a situation where I want to repeatedly pass a large node-set, which
contains a set of root nodes from various documents, as a global XSLT
parameter into multiple stylesheets. The node-set stays the same and the
stylesheets change. For some reason, I'm having serious performance problems
when passing XNodeSet in as a parameter. In fact, in most cases it's faster
to re-parse the entire set of documents using the document() function
repeatedly at run-time! I'm using xalan-j_2_1_0.

Here are the relevant code snippets:

Example stylesheet:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="foo"/>

<!-- using document() function works *much* faster, despite the need to
re-parse on the fly -->
<!-- <xsl:variable name="foo" select="document('a.xml') |
document('b.xml')"/> -->

  <xsl:template match="/">
    <xsl:copy-of select="$foo//item"/>
  </xsl:template>

</xsl:stylesheet>


Java:
First, I construct an instance of XNodeSet which contains a set of root
nodes:

    private DocumentBuilderFactory bFactory;
    private Hashtable database = new Hashtable();
    private XNodeSet nodeSet;
    private File databaseDir;

. . .

        for (int i = 0; i < fileNames.length; i++)
        {
            File file = new File(databaseDir, fileNames[i]);

            if (!file.isDirectory())
            {
                DocumentBuilder builder = bFactory.newDocumentBuilder();
                Document doc = builder.parse(file);
                database.put(fileNames[i], doc);
            }

        }

        NodeSet tempNodeSet = new NodeSet();
        Enumeration enum = database.elements();
        while (enum.hasMoreElements())
        {
            tempNodeSet.addElement((Node)enum.nextElement());
        }
        nodeSet = new XNodeSet(tempNodeSet);

. . .

Then, I repeatedly invoke different transformations using the same node-set
parameter. Each invocation takes approximately 8 times as long as if I were
to use the document() function, parsing the documents over and over again!

            transformer.setParameter("foo", nodeSet);
            transformer.transform(source, new StreamResult(out));


My expectation is that performance should be better constructing XNodeSet
once as opposed to invoking document() repeatedly, but exactly the reverse
is true! If anyone can tell me what's going on or point me to a different
object that I should be using (as opposed to XNodeSet), I'd greatly
appreciate it. I suspect that I should be building XNodeSet in a different
way (as opposed to accumulating DOM instances); I'd appreciate any direction
in how to do this.

Thanks,

Evan Lenz
XYZFind Corp.