continue;
}
// Query from the node, according the the select pattern in the
// use attribute in xsl:key.
XObject xuse = kd.m_use.execute(xmlLiaison, testNode, nscontext);
NodeList nl = null;
int nUseValues;
String exprResult = null;
if(xuse.getType() != xuse.CLASS_NODESET)
{
nUseValues = 1;
exprResult = xuse.str();
}
else
{
nl = xuse.nodeset();
if(0 == nl.getLength())
{
kd.m_buildState = KeyDeclaration.BUILT;
continue;
}
// Use each node in the node list as a key value that we'll be
// able to use to look up the given node.
nUseValues = nl.getLength();
}
for(int k = 0; k < nUseValues; k++)
{
// Use getExpr to get the string value of the given node. I hope
// the string assumption is the right thing... I can't see how
// it could work any other way.
if(null != nl)
{
Node useNode = nl.item(k);
exprResult = XMLParserLiaisonDefault.getNodeData(useNode);
}
if(null == exprResult)
continue;
// Look to see if there's already a table indexed by the
// name attribute on xsl:key. If there's not, create one.
Hashtable namedKeyTable;
{
Object keyTableObj = m_keys.get(kd.m_name);
if(null == keyTableObj)
{
namedKeyTable = new Hashtable();
m_keys.put(kd.m_name, namedKeyTable);
}
else
{
namedKeyTable = (Hashtable)keyTableObj;
}
}
// Look to see if we already have row indexed by
// the node value, which is one of the nodes found via
// the use attribute of xsl:key. If there's not a row,
// create one.
NodeListImpl keyNodes;
{
Object nodeListObj = namedKeyTable.get(exprResult);
if(null == nodeListObj)
{
keyNodes = new NodeListImpl();
namedKeyTable.put(exprResult, keyNodes);
}
else
{
keyNodes = (NodeListImpl)nodeListObj;
}
}
// See if the matched node is already in the
// table set. If it is there, we're done, otherwise
// add it.
boolean foundit = false;
int nKeyNodes = keyNodes.size();
for(int j = 0; j < nKeyNodes; j++)
{
if(testNode == keyNodes.item(j))
{
foundit = true;
break;
}
} // end for j
if(!foundit)
{
keyNodes.addElement(testNode);
}
} // end for(int k = 0; k < nUseValues; k++)
kd.m_buildState = KeyDeclaration.BUILT;
break;
} // end for(int i = 0; i < nDeclarations; i++)
// Need to break out of main loop?
if (breakout)
break;
}
}
catch(ClassCastException cce)
{
Node pos = startNode;
// Do a non-recursive pre-walk over the tree.
while(null != pos)
{
int nDeclarations = keyDeclarations.size();
// We're going to have to walk the attribute list
// if it's an element, so get the attributes.
NamedNodeMap attrs = null;
int nNodes;
if(Node.ELEMENT_NODE == pos.getNodeType())
{
attrs = ((Element)pos).getAttributes();
nNodes = attrs.getLength();
if(0 == nNodes)
attrs = null;
}
else
{
nNodes = 0;
}
// Walk the primary node, and each of the attributes.
// This loop is a little strange... it is meant to always
// execute once, then execute for each of the attributes.
Node testNode = pos;
for(int nodeIndex = -1; nodeIndex < nNodes;)
{
// Walk through each of the declarations made with xsl:key
for(int i = 0; i < nDeclarations; i++)
{
KeyDeclaration kd = (KeyDeclaration)keyDeclarations.elementAt(i);
if(!kd.m_name.equals(name))
continue;
// We are currently processing this key declaration.
// More than likely, the key function was called in the
// xsl:key declaration using the same key name.
if( kd.m_buildState == KeyDeclaration.BUILDING)
{
return;
// break;
}
kd.m_buildState = KeyDeclaration.BUILDING;
// See if our node matches the given key declaration according to
// the match attribute on xsl:key.
double score = kd.m_match.getMatchScore(execContext, testNode);
if(score == kd.m_match.MATCH_SCORE_NONE)
{
kd.m_buildState = KeyDeclaration.BUILT;
continue;
}
// Query from the node, according the the select pattern in the
// use attribute in xsl:key.
XObject xuse = kd.m_use.execute(execContext, testNode, nscontext);
NodeList nl = null;
int nUseValues;
String exprResult = null;
if(xuse.getType() != xuse.CLASS_NODESET)
{
nUseValues = 1;
exprResult = xuse.str();
}
else
{
nl = xuse.nodeset();
if(0 == nl.getLength())
{
kd.m_buildState = KeyDeclaration.BUILT;
continue;
}