sboag 00/02/21 00:14:30
Modified: src makexslt4j
src/org/apache/xalan/xpath ExtensionFunctionHandler.java
FuncNormalizeSpace.java Function.java XNodeSet.java
XPath.java
src/org/apache/xalan/xpath/xml IntVector.java
MutableAttrListImpl.java QName.java
StringToStringTable.java
XMLParserLiaisonDefault.java
src/org/apache/xalan/xslt Arg.java ElemApplyImport.java
ElemApplyTemplates.java ElemCallTemplate.java
ElemChoose.java ElemCopyOf.java
ElemExtensionCall.java ElemLiteralResult.java
ElemParam.java ElemTemplateElement.java
ElemVariable.java ExtensionNSHandler.java
Stylesheet.java StylesheetHandler.java
StylesheetRoot.java TemplateList.java
XSLTEngineImpl.java
src/org/apache/xalan/xslt/extensions Redirect.java
Added: src/org/apache/xalan/xslt VariableStack.java
Log:
Move Variable stack from inner class and optimize; General optimizations;
Regression bug fixes.
Revision Changes Path
1.8 +1 -0 xml-xalan/src/makexslt4j
Index: makexslt4j
===================================================================
RCS file: /home/cvs/xml-xalan/src/makexslt4j,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- makexslt4j 2000/02/18 06:41:37 1.7
+++ makexslt4j 2000/02/21 08:14:25 1.8
@@ -81,6 +81,7 @@
$(XSLT4JDIR)$(PATHSEP)XSLTProcessor.java \
$(XSLT4JDIR)$(PATHSEP)XSLTProcessorFactory.java \
$(XSLT4JDIR)$(PATHSEP)XSLTEngineImpl.java \
+ $(XSLT4JDIR)$(PATHSEP)VariableStack.java \
$(XSLT4JDIR)$(PATHSEP)XSLProcessorContext.java \
$(XSLT4JDIR)$(PATHSEP)XSLProcessorException.java \
$(XSLT4JDIR)$(PATHSEP)XSLProcessorVersion.java \
1.9 +6 -0
xml-xalan/src/org/apache/xalan/xpath/ExtensionFunctionHandler.java
Index: ExtensionFunctionHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/ExtensionFunctionHandler.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ExtensionFunctionHandler.java 2000/02/17 13:06:23 1.8
+++ ExtensionFunctionHandler.java 2000/02/21 08:14:25 1.9
@@ -216,6 +216,8 @@
methodArgs = new Object[args.length-1];
System.arraycopy (args, 1, methodArgs, 0, args.length - 1);
}
+ else
+ methodArgs = null;
}
else
{
@@ -527,6 +529,10 @@
msg = msg.substring("Stopping after fatal error:".length());
}
System.out.println("Call to extension function failed: "+msg);
+ }
+ else
+ {
+ throw new XPathProcessorException ("Extension not found");
}
}
return new XNull();
1.5 +5 -5
xml-xalan/src/org/apache/xalan/xpath/FuncNormalizeSpace.java
Index: FuncNormalizeSpace.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/FuncNormalizeSpace.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FuncNormalizeSpace.java 2000/01/05 23:05:25 1.4
+++ FuncNormalizeSpace.java 2000/02/21 08:14:25 1.5
@@ -78,19 +78,19 @@
throws org.xml.sax.SAXException
{
int nArgs = args.size();
- XObject obj;
if(nArgs > 0)
{
if(nArgs > 1)
path.error(context,
XPATHErrorResources.ER_NORMALIZESPACE_HAS_TOO_MANY_ARGS); //"normalize-space()
has too many arguments.");
- obj = ((XObject)args.elementAt(0));
+
+ String s1 = ((XObject)args.elementAt(0)).str();
+ return new XString(fixWhiteSpace(s1, true, true, false));
}
else
{
- obj = new XNodeSet(context);
+ String s1 = XNodeSet.getStringFromNode(context);
+ return new XString(fixWhiteSpace(s1, true, true, false));
}
- String s1 = obj.str();
- return new XString(fixWhiteSpace(s1, true, true, false));
}
/**
1.3 +34 -2 xml-xalan/src/org/apache/xalan/xpath/Function.java
Index: Function.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/Function.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Function.java 1999/11/28 04:25:07 1.2
+++ Function.java 2000/02/21 08:14:25 1.3
@@ -70,7 +70,39 @@
* @param args A list of XObject arguments.
* @return A valid XObject.
*/
- public abstract XObject execute(XPath path, XPathSupport execContext, Node
context,
+ public XObject execute(XPath path, XPathSupport execContext, Node context,
int opPos, Vector args)
- throws org.xml.sax.SAXException;
+ throws org.xml.sax.SAXException
+ {
+ // Programmer's assert. (And, no, I don't want the method to be
abstract).
+ System.out.println("Error! Function.execute should not be called!");
+ return null;
+ }
+
+ /**
+ * Execute an XPath function object. The function must return
+ * a valid object. The function can either override this function,
+ * in which case it must handle executing it's own arguments, or
+ * it can have the functions processed for it and override the
+ * other execute function.
+ * @param path The executing xpath.
+ * @param context The current context.
+ * @param opPos The current op position.
+ * @param endFunc The op position of the end of the function.
+ * @return A valid XObject.
+ */
+ public XObject execute(XPath path, XPathSupport execContext, Node context,
int opPos,
+ int funcID, int endFunc)
+ throws org.xml.sax.SAXException
+ {
+ Vector args = new Vector();
+ while(opPos < endFunc)
+ {
+ int nextOpPos = path.getNextOpPos(opPos);
+ args.addElement(path.execute(execContext, context, opPos));
+ opPos = nextOpPos;
+ }
+ return execute(path, execContext, context, opPos, args);
+ }
+
}
1.9 +22 -45 xml-xalan/src/org/apache/xalan/xpath/XNodeSet.java
Index: XNodeSet.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XNodeSet.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- XNodeSet.java 2000/01/31 17:03:07 1.8
+++ XNodeSet.java 2000/02/21 08:14:25 1.9
@@ -111,35 +111,22 @@
{
return "#NODESET";
}
-
+
/**
* Get the string conversion from a single node.
*/
double getNumberFromNode(Node n)
{
- String s = XMLParserLiaisonDefault.getNodeData(n);
- return XString.castToNum(s);
+ return XString.castToNum(getStringFromNode(n));
}
-
/**
* Cast result object to a number.
*/
public double num()
{
- double result;
NodeList nl = nodeset();
- int nNodes = nl.getLength();
- if(nNodes > 0)
- {
- result = getNumberFromNode(nl.item(0));
- }
- else
- {
- result = Double.NaN;
- }
-
- return result;
+ return (nl.getLength() > 0) ? getNumberFromNode(nl.item(0)) : Double.NaN;
}
/**
@@ -149,26 +136,28 @@
{
return nodeset().getLength() > 0;
}
+
/**
* Get the string conversion from a single node.
*/
- String getStringFromNode(Node n)
+ static String getStringFromNode(Node n)
{
- String result;
- int t = n.getNodeType();
- if(((Node.COMMENT_NODE ==t) ||
- (Node.PROCESSING_INSTRUCTION_NODE == t)))
+ switch(n.getNodeType())
{
- result = n.getNodeValue();
+ case Node.ELEMENT_NODE:
+ case Node.DOCUMENT_NODE:
+ return XMLParserLiaisonDefault.getNodeData(n);
+ case Node.CDATA_SECTION_NODE:
+ case Node.TEXT_NODE:
+ return ((Text)n).getData();
+ case Node.COMMENT_NODE:
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ case Node.ATTRIBUTE_NODE:
+ return n.getNodeValue();
+ default:
+ return XMLParserLiaisonDefault.getNodeData(n);
}
- else
- {
- result = XMLParserLiaisonDefault.getNodeData(n);
- if(null == result)
- result = "";
- }
- return result;
}
/**
@@ -176,19 +165,8 @@
*/
public String str()
{
- String result;
NodeList nl = nodeset();
- int nNodes = nl.getLength();
- if(nNodes > 0)
- {
- Node n = nl.item(0);
- result = getStringFromNode(n);
- }
- else
- {
- result = "";
- }
- return result;
+ return (nl.getLength() > 0) ? getStringFromNode(nl.item(0)) : "";
}
/**
@@ -196,15 +174,14 @@
*/
public DocumentFragment rtree(XPathSupport support)
{
-
- DocumentFragment result =
support.getDOMFactory().createDocumentFragment();
+ DocumentFragment frag = support.getDOMFactory().createDocumentFragment();
NodeList nl = nodeset();
int nNodes = nl.getLength();
for(int i = 0; i < nNodes; i++)
{
- result.appendChild(nl.item(i).cloneNode(true));
+ frag.appendChild(nl.item(i).cloneNode(true));
}
- return result;
+ return frag;
}
/**
1.18 +181 -270 xml-xalan/src/org/apache/xalan/xpath/XPath.java
Index: XPath.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/XPath.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- XPath.java 2000/02/17 13:06:24 1.17
+++ XPath.java 2000/02/21 08:14:25 1.18
@@ -547,8 +547,8 @@
opPos = getFirstChildPos(opPos);
int expr2Pos = getNextOpPos(opPos);
- XObject expr1 = execute(execContext, context, opPos);
- XObject expr2 = execute(execContext, context, expr2Pos);
+ XObject expr1 = execute(execContext, context, opPos, null, null, true);
+ XObject expr2 = execute(execContext, context, expr2Pos, null, null,
true);
return expr1.equals(expr2) ? m_true : m_false;
}
@@ -1078,16 +1078,6 @@
return result;
}
- /**
- * Handle a built-in function.
- */
- protected XObject function(XPathSupport execContext, Node context, int
opPos,
- int funcID,
- Vector args)
- throws org.xml.sax.SAXException
- {
- return m_functions[funcID].execute(this, execContext, context, opPos,
args);
- }
/**
* Computes the union of its operands which must be node-sets.
@@ -1223,6 +1213,51 @@
}
return targetStrings;
}
+
+ /**
+ * Execute an extension function from an op code.
+ */
+ private XObject executeExtension(XPathSupport execContext, Node context,
int opPos)
+ throws org.xml.sax.SAXException
+ {
+ int endExtFunc = opPos+m_opMap[opPos+1]-1;
+ opPos = getFirstChildPos(opPos);
+ String ns = (String)m_tokenQueue[m_opMap[opPos]];
+ opPos++;
+ String funcName = (String)m_tokenQueue[m_opMap[opPos]];
+ opPos++;
+ Vector args = new Vector();
+ while(opPos < endExtFunc)
+ {
+ int nextOpPos = getNextOpPos(opPos);
+ args.addElement( execute(execContext, context, opPos) );
+ opPos = nextOpPos;
+ }
+ return extfunction(execContext, context, opPos, ns, funcName, args,
+ // Create a method key, for faster lookup.
+
String.valueOf(m_opMap[opPos])+String.valueOf(((Object)this).hashCode()));
+ }
+
+ /**
+ * Execute a function from an op code.
+ */
+ XObject executeFunction(XPathSupport execContext, Node context, int opPos)
+ throws org.xml.sax.SAXException
+ {
+ int endFunc = opPos+m_opMap[opPos+1]-1;
+ opPos = getFirstChildPos(opPos);
+ int funcID = m_opMap[opPos];
+ opPos++;
+ if(-1 != funcID)
+ {
+ return m_functions[funcID].execute(this, execContext, context, opPos,
funcID, endFunc);
+ }
+ else
+ {
+ warn(XPATHErrorResources.WG_FUNCTION_TOKEN_NOT_FOUND); //"function
token not found.");
+ return null;
+ }
+ }
/**
* Execute the XPath object.
@@ -1237,7 +1272,44 @@
Node context, int opPos)
throws org.xml.sax.SAXException
{
- return execute(execContext, context, opPos, null, null, false);
+ int op = m_opMap[opPos];
+ switch(op)
+ {
+ case OP_XPATH: return execute(execContext, context, opPos+2);
+ case OP_OR: return or(execContext, context, opPos);
+ case OP_AND: return and(execContext, context, opPos);
+ case OP_NOTEQUALS: return notequals(execContext, context, opPos);
+ case OP_EQUALS: return equals(execContext, context, opPos);
+ case OP_LTE: return lte(execContext, context, opPos);
+ case OP_LT: return lt(execContext, context, opPos);
+ case OP_GTE: return gte(execContext, context, opPos);
+ case OP_GT: return gt(execContext, context, opPos);
+ case OP_PLUS: return plus(execContext, context, opPos);
+ case OP_MINUS: return minus(execContext, context, opPos);
+ case OP_MULT: return mult(execContext, context, opPos);
+ case OP_DIV: return div(execContext, context, opPos);
+ case OP_MOD: return mod(execContext, context, opPos);
+ case OP_QUO: return quo(execContext, context, opPos);
+ case OP_NEG: return neg(execContext, context, opPos);
+ case OP_STRING: return string(execContext, context, opPos);
+ case OP_BOOL: return bool(execContext, context, opPos);
+ case OP_NUMBER: return number(execContext, context, opPos);
+ case OP_UNION: return union(execContext, context, opPos, null, null);
+ case OP_LITERAL: return literal(execContext, context, opPos);
+ case OP_VARIABLE: return variable(execContext, context, opPos);
+ case OP_GROUP: return group(execContext, context, opPos);
+ case OP_NUMBERLIT: return numberlit(execContext, context, opPos);
+ case OP_ARGUMENT: return arg(execContext, context, opPos);
+ case OP_EXTFUNCTION: return executeExtension(execContext, context,
opPos);
+ case OP_FUNCTION: return executeFunction(execContext, context, opPos);
+ case OP_LOCATIONPATH: return locationPath(execContext, context, opPos,
null, null, false);
+ case OP_PREDICATE: return null; // should never hit this here.
+ case OP_MATCHPATTERN: return matchPattern(execContext, context, opPos+2);
+ case OP_LOCATIONPATHPATTERN: return locationPathPattern(execContext,
context, opPos);
+ default: if(op == OP_LOCATIONPATH_EX) return locationPath(execContext,
context, opPos, null, null, false);
+ else error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new
Object[] {Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code:
"+m_opMap[opPos]);
+ }
+ return null;
}
/**
@@ -1249,211 +1321,50 @@
* @param callbackInfo Object that will be passed to the
processLocatedNode method.
* @return The result of the XPath.
*/
- public XObject execute(XPathSupport execContext,
- Node context, int opPos,
+ public XObject execute(XPathSupport execContext, Node context, int opPos,
NodeCallback callback, Object callbackInfo, boolean
stopAtFirst)
throws org.xml.sax.SAXException
{
- XObject result = null;
- boolean doLoop = true;
- while(doLoop)
+ int op = m_opMap[opPos];
+ switch(op)
{
- switch(m_opMap[opPos])
- {
- case OP_XPATH:
- opPos+=2;
- continue;
- case OP_MATCHPATTERN:
- result = matchPattern(execContext, context, opPos+2);
- break;
- case EMPTY:
- opPos++;
- break;
- case OP_OR:
- result = or(execContext, context, opPos);
- break;
- case OP_AND:
- result = and(execContext, context, opPos);
- break;
- case OP_NOTEQUALS:
- result = notequals(execContext, context, opPos);
- break;
- case OP_EQUALS:
- result = equals(execContext, context, opPos);
- break;
- case OP_LTE:
- result = lte(execContext, context, opPos);
- break;
- case OP_LT:
- result = lt(execContext, context, opPos);
- break;
- case OP_GTE:
- result = gte(execContext, context, opPos);
- break;
- case OP_GT:
- result = gt(execContext, context, opPos);
- break;
- case OP_PLUS:
- result = plus(execContext, context, opPos);
- break;
- case OP_MINUS:
- result = minus(execContext, context, opPos);
- break;
- case OP_MULT:
- result = mult(execContext, context, opPos);
- break;
- case OP_DIV:
- result = div(execContext, context, opPos);
- break;
- case OP_MOD:
- result = mod(execContext, context, opPos);
- break;
- case OP_QUO:
- result = quo(execContext, context, opPos);
- break;
- case OP_NEG:
- result = neg(execContext, context, opPos);
- break;
- case OP_STRING:
- result = string(execContext, context, opPos);
- break;
- case OP_BOOL:
- result = bool(execContext, context, opPos);
- break;
- case OP_NUMBER:
- result = number(execContext, context, opPos);
- break;
- case OP_UNION:
- result = union(execContext, context, opPos, callback,
callbackInfo);
- break;
- case OP_LITERAL:
- result = literal(execContext, context, opPos);
- break;
- case OP_VARIABLE:
- result = variable(execContext, context, opPos);
- break;
- case OP_GROUP:
- result = group(execContext, context, opPos);
- break;
- case OP_NUMBERLIT:
- result = numberlit(execContext, context, opPos);
- break;
- case OP_ARGUMENT:
- result = arg(execContext, context, opPos);
- break;
- case OP_EXTFUNCTION:
- {
- int endExtFunc = opPos+m_opMap[opPos+1]-1;
- opPos = getFirstChildPos(opPos);
- String ns = (String)m_tokenQueue[m_opMap[opPos]];
- opPos++;
- String funcName = (String)m_tokenQueue[m_opMap[opPos]];
- opPos++;
- Vector args = new Vector();
- while(opPos < endExtFunc)
- {
- int nextOpPos = getNextOpPos(opPos);
- args.addElement( execute(execContext, context, opPos) );
- opPos = nextOpPos;
- }
- result = extfunction(execContext, context, opPos, ns, funcName,
args,
- // Create a method key, for faster lookup.
-
String.valueOf(m_opMap[opPos])+String.valueOf(((Object)this).hashCode()));
- }
- break;
- case OP_FUNCTION:
- {
- int endFunc = opPos+m_opMap[opPos+1]-1;
- opPos = getFirstChildPos(opPos);
- int funcID = m_opMap[opPos];
- opPos++;
- Vector args = new Vector();
- while(opPos < endFunc)
- {
- int nextOpPos = getNextOpPos(opPos);
- args.addElement(execute(execContext, context, opPos));
- opPos = nextOpPos;
- }
- if(-1 != funcID)
- {
- result = function(execContext, context, opPos, funcID, args);
- }
- else
- {
- warn(XPATHErrorResources.WG_FUNCTION_TOKEN_NOT_FOUND);
//"function token not found.");
- }
- }
- break;
- case OP_LOCATIONPATH_EX:
- case OP_LOCATIONPATH:
- result = locationPath(execContext, context, opPos, callback,
callbackInfo, stopAtFirst);
- break;
- case OP_LOCATIONPATHPATTERN:
- result = locationPathPattern(execContext, context, opPos);
- break;
- /*
- case OP_PREDICATE:
- break;
- case FROM_ANCESTORS:
- break;
- case FROM_ANCESTORS_OR_SELF:
- break;
- case FROM_ATTRIBUTES:
- break;
- case FROM_CHILDREN:
- break;
- case FROM_DESCENDANTS:
- break;
- case FROM_DESCENDANTS_OR_SELF:
- break;
- case FROM_FOLLOWING:
- break;
- case FROM_FOLLOWING_SIBLINGS:
- break;
- case FROM_PARENT:
- break;
- case FROM_PRECEDING:
- break;
- case FROM_PRECEDING_SIBLINGS:
- break;
- case FROM_SELF:
- break;
- case FROM_NAMESPACE:
- break;
- // case FROM_ATTRIBUTE:
- // break;
- // case FROM_DOC:
- // break;
- // case FROM_DOCREF:
- // break;
- // case FROM_ID:
- // break;
- // case FROM_IDREF:
- // break;
- case FROM_ROOT:
- break;
- case NODETYPE_COMMENT:
- break;
- case NODETYPE_TEXT:
- break;
- case NODETYPE_PI:
- break;
- case NODETYPE_NODE:
- break;
- case NODETYPE_ROOT:
- break;
- case NODETYPE_ANYELEMENT:
- break;
- case NODENAME:
- break;
- */
- default:
- error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new Object[]
{Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code:
"+m_opMap[opPos]);
- }
- doLoop = false;
+ case OP_XPATH: return execute(execContext, context, opPos+2, callback,
callbackInfo, stopAtFirst);
+ case OP_OR: return or(execContext, context, opPos);
+ case OP_AND: return and(execContext, context, opPos);
+ case OP_NOTEQUALS: return notequals(execContext, context, opPos);
+ case OP_EQUALS: return equals(execContext, context, opPos);
+ case OP_LTE: return lte(execContext, context, opPos);
+ case OP_LT: return lt(execContext, context, opPos);
+ case OP_GTE: return gte(execContext, context, opPos);
+ case OP_GT: return gt(execContext, context, opPos);
+ case OP_PLUS: return plus(execContext, context, opPos);
+ case OP_MINUS: return minus(execContext, context, opPos);
+ case OP_MULT: return mult(execContext, context, opPos);
+ case OP_DIV: return div(execContext, context, opPos);
+ case OP_MOD: return mod(execContext, context, opPos);
+ case OP_QUO: return quo(execContext, context, opPos);
+ case OP_NEG: return neg(execContext, context, opPos);
+ case OP_STRING: return string(execContext, context, opPos);
+ case OP_BOOL: return bool(execContext, context, opPos);
+ case OP_NUMBER: return number(execContext, context, opPos);
+ case OP_UNION: return union(execContext, context, opPos, callback,
callbackInfo);
+ case OP_LITERAL: return literal(execContext, context, opPos);
+ case OP_VARIABLE: return variable(execContext, context, opPos);
+ case OP_GROUP: return group(execContext, context, opPos);
+ case OP_NUMBERLIT: return numberlit(execContext, context, opPos);
+ case OP_ARGUMENT: return arg(execContext, context, opPos);
+ case OP_EXTFUNCTION: return executeExtension(execContext, context,
opPos);
+ case OP_FUNCTION: return executeFunction(execContext, context, opPos);
+ case OP_LOCATIONPATH: return locationPath(execContext, context, opPos,
callback, callbackInfo, stopAtFirst);
+ case OP_PREDICATE: return null; // should never hit this here.
+ case OP_MATCHPATTERN: return matchPattern(execContext, context, opPos+2);
+ case OP_LOCATIONPATHPATTERN: return locationPathPattern(execContext,
context, opPos);
+ default: if(op == OP_LOCATIONPATH_EX) return locationPath(execContext,
context, opPos, callback, callbackInfo, stopAtFirst);
+ else error(context, XPATHErrorResources.ER_UNKNOWN_OPCODE, new
Object[] {Integer.toString(m_opMap[opPos])}); //"ERROR! Unknown op code:
"+m_opMap[opPos]);
+ }
+
+ return null;
}
- return result;
-}
// ============= Op Code Position Helper Functions =================
private void ____OPCODE_POSITION_HELPER_FUNCTIONS____(){}
@@ -1974,6 +1885,41 @@
public static final int OP_ARGUMENT = 25;
/**
+ * [OP_EXTFUNCTION] (Extension function.)
+ * [length]
+ * [index to namespace token]
+ * [index to function name token]
+ * {OP_ARGUMENT}*
+ *
+ * returns:
+ * XNodeSet
+ * XNumber
+ * XString
+ * XBoolean
+ * XRTree
+ * XObject
+ */
+ public static final int OP_EXTFUNCTION = 26;
+
+
+ /**
+ * [OP_FUNCTION]
+ * [length]
+ * [FUNC_name]
+ * {OP_ARGUMENT}*
+ * [ENDOP]
+ *
+ * returns:
+ * XNodeSet
+ * XNumber
+ * XString
+ * XBoolean
+ * XRTree
+ * XObject
+ */
+ public static final int OP_FUNCTION = 27;
+
+ /**
* [OP_LOCATIONPATH]
* [length]
* {FROM_stepType}
@@ -2004,6 +1950,28 @@
public static final int OP_PREDICATE = 29;
/**
+ * [OP_UNION]
+ * [length]
+ * {PathExpr}+
+ *
+ * returns:
+ * XNodeSet
+ */
+ public static final int OP_MATCHPATTERN = 30;
+
+
+ /**
+ * [OP_UNION]
+ * [length]
+ * {PathExpr}+
+ *
+ * returns:
+ * XNodeSet
+ */
+ public static final int OP_LOCATIONPATHPATTERN = 31;
+
+
+ /**
* [NODETYPE_COMMENT]
* No size or arguments.
* Note: must not overlap function OP number!
@@ -2205,63 +2173,6 @@
m_functions[FUNC_UNPARSED_ENTITY_URI] = new
FuncLoader("FuncUnparsedEntityURI", FUNC_UNPARSED_ENTITY_URI);
}
-
- /**
- * [OP_EXTFUNCTION] (Extension function.)
- * [length]
- * [index to namespace token]
- * [index to function name token]
- * {OP_ARGUMENT}*
- *
- * returns:
- * XNodeSet
- * XNumber
- * XString
- * XBoolean
- * XRTree
- * XObject
- */
- public static final int OP_EXTFUNCTION = 26;
-
-
- /**
- * [OP_FUNCTION]
- * [length]
- * [FUNC_name]
- * {OP_ARGUMENT}*
- * [ENDOP]
- *
- * returns:
- * XNodeSet
- * XNumber
- * XString
- * XBoolean
- * XRTree
- * XObject
- */
- public static final int OP_FUNCTION = 27;
-
-
- /**
- * [OP_UNION]
- * [length]
- * {PathExpr}+
- *
- * returns:
- * XNodeSet
- */
- public static final int OP_MATCHPATTERN = 92;
-
-
- /**
- * [OP_UNION]
- * [length]
- * {PathExpr}+
- *
- * returns:
- * XNodeSet
- */
- public static final int OP_LOCATIONPATHPATTERN = 93;
// For match patterns
public static final int MATCH_ATTRIBUTE = 94;
1.3 +1 -1 xml-xalan/src/org/apache/xalan/xpath/xml/IntVector.java
Index: IntVector.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/IntVector.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- IntVector.java 2000/02/13 16:42:43 1.2
+++ IntVector.java 2000/02/21 08:14:26 1.3
@@ -162,7 +162,7 @@
{
if(m_map[i] == s)
{
- if(i > m_firstFree)
+ if((i+1) < m_firstFree)
System.arraycopy(m_map, i+1, m_map, i-1, m_firstFree-i);
else
m_map[i] = java.lang.Integer.MIN_VALUE;
1.4 +2 -2
xml-xalan/src/org/apache/xalan/xpath/xml/MutableAttrListImpl.java
Index: MutableAttrListImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/MutableAttrListImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- MutableAttrListImpl.java 2000/02/18 17:48:34 1.3
+++ MutableAttrListImpl.java 2000/02/21 08:14:26 1.4
@@ -286,10 +286,10 @@
*/
public String getValue (String name)
{
- for(int i = 0; i <= m_firstFree; i+=SLOTS_PER_ATTR)
{
+ for(int i = 0; i < m_firstFree; i+=SLOTS_PER_ATTR)
{
if(m_map[i+OFFSET_NAME].equals(name))
{
- return m_map[i+OFFSET_NAME];
+ return m_map[i+OFFSET_VALUE];
}
}
return null;
}
}
1.2 +12 -0 xml-xalan/src/org/apache/xalan/xpath/xml/QName.java
Index: QName.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/QName.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- QName.java 1999/11/08 20:55:56 1.1
+++ QName.java 2000/02/21 08:14:26 1.2
@@ -131,6 +131,18 @@
}
/**
+ * Construct a QName from a string, without namespace resolution. Good
+ * for a few odd cases.
+ */
+ public QName(String qname)
+ {
+ m_namespace = null;
+
+ m_localpart = qname;
+ m_hashCode = m_localpart.hashCode();
+ }
+
+ /**
* Construct a QName from a string, resolving the prefix
* using the given namespace stack. The default namespace is
* not resolved.
1.3 +20 -0
xml-xalan/src/org/apache/xalan/xpath/xml/StringToStringTable.java
Index: StringToStringTable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/StringToStringTable.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- StringToStringTable.java 1999/12/13 07:40:11 1.2
+++ StringToStringTable.java 2000/02/21 08:14:26 1.3
@@ -126,6 +126,26 @@
}
return null;
}
+
+ /**
+ * Tell if the table contains the given string.
+ */
+ public final void remove(String key)
+ {
+ for(int i = 0; i < m_firstFree; i+=2)
+ {
+ if(m_map[i].equals(key))
+ {
+ if((i+2) < m_firstFree)
+ System.arraycopy(m_map, i+2, m_map, i, m_firstFree-(i+2));
+ m_firstFree -= 2;
+ m_map[m_firstFree] = null;
+ m_map[m_firstFree+1] = null;
+ break;
+ }
+ }
+ }
+
/**
* Tell if the table contains the given string.
1.25 +34 -45
xml-xalan/src/org/apache/xalan/xpath/xml/XMLParserLiaisonDefault.java
Index: XMLParserLiaisonDefault.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/xml/XMLParserLiaisonDefault.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- XMLParserLiaisonDefault.java 2000/02/18 18:50:28 1.24
+++ XMLParserLiaisonDefault.java 2000/02/21 08:14:26 1.25
@@ -182,11 +182,11 @@
*/
public Hashtable m_extensionFunctionNamespaces = new Hashtable();
- /**
- * The table of extension namespaces.
- * @serial
- */
- public Hashtable m_extensionNamespaces = new Hashtable();
+ /**
+ * The table of extension namespaces.
+ * @serial
+ */
+ // public Hashtable m_extensionNamespaces = new Hashtable();
/**
* Table of input documents.
@@ -561,7 +561,7 @@
stream.defaultReadObject();
m_NSInfos = new Hashtable();
m_extensionFunctionNamespaces = new Hashtable();
- m_extensionNamespaces = new Hashtable();
+ // m_extensionNamespaces = new Hashtable();
m_sourceDocs = new Hashtable();
}
catch(ClassNotFoundException cnfe)
@@ -1422,7 +1422,7 @@
return this.m_DOMFactory;
}
-
+
/**
* Get the textual contents of the node. If the node
* is an element, apply whitespace stripping rules,
@@ -1432,54 +1432,45 @@
*/
public static String getNodeData(Node node)
{
+ StringBuffer buf = new StringBuffer();
+ getNodeData(node, buf);
+ return (buf.length() > 0) ? buf.toString() : "";
+ }
+
+ /**
+ * Get the textual contents of the node. If the node
+ * is an element, apply whitespace stripping rules,
+ * though I'm not sure if this is right (I'll fix
+ * or declare victory when I review the entire
+ * whitespace handling).
+ */
+ public static void getNodeData(Node node, StringBuffer buf)
+ {
String data = null;
- switch(node.getNodeType())
+ switch(node.getNodeType())
{
case Node.DOCUMENT_FRAGMENT_NODE:
- {
- NodeList mnl = node.getChildNodes();
- StringBuffer buf = new StringBuffer();
- int n = mnl.getLength();
- for(int i = 0; i < n; i++)
{
- String nodeData = getNodeData(mnl.item(i));
- if((null != nodeData) && (nodeData.length() > 0))
- {
- buf.append(nodeData);
- }
- }
- data = buf.toString();
- }
+ NodeList mnl = node.getChildNodes();
+ int n = mnl.getLength();
+ for(int i = 0; i < n; i++)
+ getNodeData(mnl.item(i), buf);
+ }
break;
case Node.DOCUMENT_NODE:
case Node.ELEMENT_NODE:
- {
- StringBuffer buf = new StringBuffer();
-
- for(Node child = node.getFirstChild();
- null != child;
- child = child.getNextSibling())
- {
- String nodeData = getNodeData(child);
- if((null != nodeData) && (nodeData.length() > 0))
- {
- buf.append(nodeData);
- }
- }
- data = buf.toString();
- }
+ {
+ for(Node child = node.getFirstChild(); null != child; child =
child.getNextSibling())
+ getNodeData(child, buf);
+ }
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
- // if(!isIgnorableWhitespace((Text)node))
- {
- // data = fixWhiteSpace(((Text)node).getData(), false, false, true);
- data = ((Text)node).getData();
- }
+ buf.append( ((Text)node).getData() );
break;
case Node.ATTRIBUTE_NODE:
- data = node.getNodeValue();
+ buf.append( node.getNodeValue() );
break;
case Node.PROCESSING_INSTRUCTION_NODE:
// warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);
@@ -1488,8 +1479,6 @@
// ignore
break;
}
-
- return data;
}
//==========================================================
@@ -1774,7 +1763,7 @@
*/
public void addExtensionElementNamespace (String uri,
ExtensionFunctionHandler extNS) {
- m_extensionNamespaces.put (uri, extNS);
+ m_extensionFunctionNamespaces.put (uri, extNS);
}
/**
1.2 +35 -12 xml-xalan/src/org/apache/xalan/xslt/Arg.java
Index: Arg.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Arg.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Arg.java 1999/11/08 20:56:14 1.1
+++ Arg.java 2000/02/21 08:14:27 1.2
@@ -67,8 +67,19 @@
{
QName m_qname;
XObject m_val;
- String m_expression = null;
+ String m_expression;
boolean m_isParamVar;
+
+ /**
+ * Construct a dummy Macro argument.
+ */
+ Arg()
+ {
+ m_qname = new QName("");; // so that string compares can be done.
+ m_val = null;
+ m_expression = null;
+ m_isParamVar = false;
+ }
/**
* Construct a Macro argument.
@@ -89,6 +100,7 @@
m_qname = qname;
m_val = val;
m_isParamVar = false;
+ m_expression = null;
}
@@ -100,6 +112,7 @@
m_qname = qname;
m_val = val;
m_isParamVar = isParamVar;
+ m_expression = null;
}
/**
@@ -109,15 +122,21 @@
*/
public boolean equals(Object obj)
{
- if(obj instanceof QName)
+ try
{
- QName qname = (QName)obj;
- return m_qname.equals(qname.m_localpart)
- && ((null != m_qname.m_namespace) && (null !=
qname.m_namespace))
- ? m_qname.m_namespace.equals(qname.m_namespace)
- : ((null == m_qname.m_namespace) && (null ==
qname.m_namespace));
+ if(m_qname != null)
+ {
+ QName qname = (QName)obj;
+ return m_qname.equals(qname.m_localpart)
+ && ((null != m_qname.m_namespace) && (null !=
qname.m_namespace))
+ ? m_qname.m_namespace.equals(qname.m_namespace)
+ : ((null == m_qname.m_namespace) && (null ==
qname.m_namespace));
+ }
}
-
+ catch(ClassCastException cce)
+ {
+ }
+
return false;
}
@@ -128,10 +147,14 @@
*/
public boolean equals(QName qname)
{
- return m_qname.m_localpart.equals(qname.m_localpart)
- && (((null != m_qname.m_namespace) && (null !=
qname.m_namespace))
- ? m_qname.m_namespace.equals(qname.m_namespace)
- : ((null == m_qname.m_namespace) && (null ==
qname.m_namespace)));
+ if(m_qname != null)
+ {
+ return m_qname.m_localpart.equals(qname.m_localpart)
+ && (((null != m_qname.m_namespace) && (null !=
qname.m_namespace))
+ ? m_qname.m_namespace.equals(qname.m_namespace)
+ : ((null == m_qname.m_namespace) && (null ==
qname.m_namespace)));
+ }
+ return false;
}
}
1.5 +0 -1 xml-xalan/src/org/apache/xalan/xslt/ElemApplyImport.java
Index: ElemApplyImport.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemApplyImport.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ElemApplyImport.java 2000/02/11 15:42:39 1.4
+++ ElemApplyImport.java 2000/02/21 08:14:27 1.5
@@ -119,7 +119,6 @@
transformChild(
m_stylesheet, null, null,
- sourceTree,
processor.m_parserLiaison.getParentOfNode(sourceNode),
sourceNode,
mode, getXSLToken(), processor);
}
1.5 +26 -13
xml-xalan/src/org/apache/xalan/xslt/ElemApplyTemplates.java
Index: ElemApplyTemplates.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemApplyTemplates.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ElemApplyTemplates.java 2000/02/11 15:42:39 1.4
+++ ElemApplyTemplates.java 2000/02/21 08:14:27 1.5
@@ -149,19 +149,32 @@
{
mode = m_mode;
}
- transformSelectedChildren(m_stylesheet,
- this,
- null,
- sourceTree,
- sourceNode, mode,
- m_selectPattern,
- Constants.ELEMNAME_APPLY_TEMPLATES,
- processor);
-
- if(true == needToTurnOffInfiniteLoopCheck)
- {
- processor.m_needToCheckForInfiniteLoops = false;
- }
+
+ processor.getVarStack().pushParams(processor,
+ m_stylesheet,
+ this,
+ sourceTree,
+ sourceNode, mode);
+
+ try
+ {
+ transformSelectedChildren(m_stylesheet,
+ this,
+ null,
+ sourceTree,
+ sourceNode, mode,
+ m_selectPattern,
+ Constants.ELEMNAME_APPLY_TEMPLATES,
+ processor);
+ }
+ finally
+ {
+ if(true == needToTurnOffInfiniteLoopCheck)
+ {
+ processor.m_needToCheckForInfiniteLoops = false;
+ }
+ processor.getVarStack().popCurrentContext();
+ }
}
else // if(null == sourceNode)
{
1.6 +6 -8 xml-xalan/src/org/apache/xalan/xslt/ElemCallTemplate.java
Index: ElemCallTemplate.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemCallTemplate.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElemCallTemplate.java 2000/02/13 16:42:44 1.5
+++ ElemCallTemplate.java 2000/02/21 08:14:27 1.6
@@ -116,20 +116,18 @@
{
try
{
- processor.m_variableStacks.pushContextMarker(m_template, sourceNode);
+ processor.getVarStack().pushParams(processor,
+ m_stylesheet,
+ this,
+ sourceTree,
+ sourceNode, mode);
- processor.m_variableStacks.pushParams(processor.getExecContext(),
- m_stylesheet,
- this,
- sourceTree,
- sourceNode, mode, m_template);
-
// template.executeChildren(processor, sourceTree, sourceNode, mode);
m_template.execute(processor, sourceTree, sourceNode, mode);
}
finally
{
- processor.m_variableStacks.popCurrentContext();
+ processor.getVarStack().popCurrentContext();
}
}
else
1.6 +8 -8 xml-xalan/src/org/apache/xalan/xslt/ElemChoose.java
Index: ElemChoose.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemChoose.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElemChoose.java 2000/02/17 13:06:26 1.5
+++ ElemChoose.java 2000/02/21 08:14:27 1.6
@@ -100,7 +100,7 @@
SAXException
{
super.execute(processor, sourceTree, sourceNode, mode);
- boolean found = false;
+ boolean found = false;
for (ElemTemplateElement node = (ElemTemplateElement)getFirstChild();
node != null; node = node.m_nextSibling)
{
@@ -110,9 +110,9 @@
found = true;
ElemWhen when = (ElemWhen)node;
// must be xsl:when
- XPathSupport execContext = processor.getXMLProcessorLiaison();
- XObject test = when.m_test.execute(execContext, sourceNode, this);
+ XObject test = when.m_test.execute(processor.getExecContext(),
+ sourceNode, this, null, null,
true);
if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
{
m_stylesheet.m_stylesheetRoot.fireSelectedEvent(new
SelectionEvent(processor,
@@ -127,20 +127,20 @@
{
when.executeChildren(processor, sourceTree,
sourceNode, mode);
- break;
+ return;
}
}
else if(Constants.ELEMNAME_OTHERWISE == type)
{
+ found = true;
// xsl:otherwise
node.executeChildren(processor, sourceTree,
sourceNode, mode);
+ return;
}
}
- if (found == false)
- {
- processor.error(XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
- }
+ if(!found)
+ processor.error(XSLTErrorResources.ER_CHOOSE_REQUIRES_WHEN);
}
/**
1.6 +9 -3 xml-xalan/src/org/apache/xalan/xslt/ElemCopyOf.java
Index: ElemCopyOf.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemCopyOf.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElemCopyOf.java 2000/02/17 14:47:34 1.5
+++ ElemCopyOf.java 2000/02/21 08:14:27 1.6
@@ -108,9 +108,15 @@
{
super.execute(processor, sourceTree, sourceNode, mode);
XPathSupport execContext = processor.getXMLProcessorLiaison();
- processor.copyAttributesToAttList( sourceNode,
m_stylesheet.m_stylesheetRoot,
- (Element)sourceNode,
processor.m_pendingAttributes );
- processor.copySourceNSAttrs(sourceNode, processor.m_pendingAttributes);
+ /* Where did this come from? -sb
+ if(Node.ELEMENT_NODE == sourceNode.getNodeType())
+ {
+ processor.copyAttributesToAttList( (Element)sourceNode,
+ m_stylesheet.m_stylesheetRoot,
+ processor.m_pendingAttributes );
+ processor.copySourceNSAttrs(sourceNode, processor.m_pendingAttributes);
+ }
+ */
XObject value = m_selectPattern.execute(execContext, sourceNode, this);
if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
1.7 +40 -59
xml-xalan/src/org/apache/xalan/xslt/ElemExtensionCall.java
Index: ElemExtensionCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemExtensionCall.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ElemExtensionCall.java 2000/02/17 13:06:26 1.6
+++ ElemExtensionCall.java 2000/02/21 08:14:27 1.7
@@ -65,6 +65,7 @@
import org.apache.xalan.xpath.xml.StringToStringTable;
import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
import org.apache.xalan.xpath.xml.MutableAttrListImpl;
+import org.apache.xalan.xpath.XPathSupport;
import java.io.*;
import java.util.*;
@@ -76,9 +77,7 @@
String m_extHandlerLookup;
String localPart;
AttributeList m_attrs;
- public Vector m_avts = null;
- public StringToStringTable m_excludeResultPrefixes = null;
- public String m_extensionElementPrefixes[] = null;
+ // public Vector m_avts = null;
transient boolean isAvailable = false;
String m_lang;
String m_srcURL;
@@ -117,7 +116,7 @@
boolean isClass = false;
if (cname.startsWith ("class:"))
{
- cname = m_scriptSrc.substring (6);
+ cname = cname.substring (6);
isClass = true;
}
// m_javaClass = Class.forName (cname);
@@ -128,63 +127,16 @@
throw new XSLProcessorException (e.getMessage (), e);
}
}
+
+ // Make a copy of the attributes, so we can give them to the
+ // extension in raw form. The alternative to doing this is to
+ // reconstruct the list in raw form.
+ m_attrs = new MutableAttrListImpl(atts);
// this.nsh = nsh;
//
processor.getXMLProcessorLiaison().addExtensionNamespace(m_extHandlerLookup,
nsh);
this.localPart = localPart;
m_attrs = new MutableAttrListImpl(atts);
- int nAttrs = atts.getLength();
- for(int i = 0; i < nAttrs; i++)
- {
- String aname = atts.getName(i);
- boolean needToProcess = true;
- int indexOfNSSep = aname.indexOf(':');
- String prefix;
- if(indexOfNSSep > 0)
- {
- prefix = aname.substring(0, indexOfNSSep);
- if(!prefix.equals("xmlns"))
- {
- String ns = getNamespaceForPrefix(prefix);
- if((null != ns)
- && ns.equals( m_stylesheet.m_XSLNameSpaceURL ))
- {
- String localName = aname.substring(indexOfNSSep+1);
- if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
- {
- needToProcess = false;
- String qnames = atts.getValue(i);
- StringTokenizer tokenizer = new StringTokenizer(qnames, "
\t\n\r", false);
- m_extensionElementPrefixes = new
String[tokenizer.countTokens()];
- for(int k = 0; tokenizer.hasMoreTokens(); k++)
- {
- m_extensionElementPrefixes[k] = tokenizer.nextToken();
- m_excludeResultPrefixes =
m_stylesheet.processExcludeResultPrefixes(m_extensionElementPrefixes[k], null);
- }
- }
- else
if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
- {
- needToProcess = false;
- m_excludeResultPrefixes =
m_stylesheet.processExcludeResultPrefixes(atts.getValue(i), null);
- }
- }
- }
- }
- if(needToProcess)
- {
- boolean _processUseAttributeSets = processUseAttributeSets(aname,
atts, i);
- boolean _processSpaceAttr = processSpaceAttr(aname, atts, i);
- if(!(isAttrOK(aname, atts, i) || _processUseAttributeSets ||
_processSpaceAttr))
- {
- if(null == m_avts)
- m_avts = new Vector(nAttrs);
- // resultAttrs.addAttribute(atts.getName(i), atts.getType(i),
atts.getValue(i));
- m_avts.addElement(new AVT(aname, atts.getType(i), atts.getValue(i),
- this, m_stylesheet, processor));
- }
- }
- }
-
}
/**
@@ -210,7 +162,7 @@
processor.flushPending();
XMLParserLiaisonDefault liaison =
((XMLParserLiaisonDefault)processor.getXMLProcessorLiaison());
ExtensionNSHandler nsh
- = (ExtensionNSHandler)liaison.m_extensionNamespaces.get(m_extns);
+ =
(ExtensionNSHandler)liaison.m_extensionFunctionNamespaces.get(m_extns);
if(null == nsh)
{
@@ -221,7 +173,7 @@
nsh.processElement (localPart, this,
processor,
m_stylesheet,
- sourceTree, sourceNode, mode, m_javaClass);
+ sourceTree, sourceNode, mode, m_javaClass, this);
}
catch(Exception e)
{
@@ -248,9 +200,38 @@
}
}
+ /**
+ * Return the raw value of the attribute.
+ */
public String getAttribute(String name)
{
- return m_attrs.getValue(name);
+ String value = m_attrs.getValue(name);
+ return value;
+ }
+
+ /**
+ * Return the value of the attribute interpreted as an Attribute
+ * Value Template (in other words, you can use curly expressions
+ * such as href="http://{website}".
+ */
+ public String getAttribute(String name, Node sourceNode, XSLTEngineImpl
processor)
+ throws SAXException
+ {
+ if(null != m_avts)
+ {
+ int nAttrs = m_avts.size();
+ for(int i = (nAttrs-1); i >= 0; i--)
+ {
+ AVT avt = (AVT)m_avts.elementAt(i);
+ if(avt.m_name.equals(name))
+ {
+ XPathSupport execContext = processor.getXMLProcessorLiaison();
+ return avt.evaluate(execContext, sourceNode, this,
+ new StringBuffer());
+ }
+ } // end for
+ }
+ return null;
}
}
1.16 +22 -48
xml-xalan/src/org/apache/xalan/xslt/ElemLiteralResult.java
Index: ElemLiteralResult.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemLiteralResult.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ElemLiteralResult.java 2000/02/18 16:48:38 1.15
+++ ElemLiteralResult.java 2000/02/21 08:14:27 1.16
@@ -72,10 +72,16 @@
public class ElemLiteralResult extends ElemUse
{
- public String m_extensionElementPrefixes[] = null;
public Vector m_avts = null;
public String m_qname;
- public StringToStringTable m_excludeResultPrefixes = null;
+ public String m_extensionElementPrefixes[] = null;
+
+ /**
+ * This is in support of the exclude-result-prefixes
+ * attribute. It is really needed only at construction
+ * time, and so should probably go somewhere else.
+ */
+ protected StringToStringTable m_excludeResultPrefixes = null;
public int getXSLToken()
{
@@ -106,29 +112,16 @@
if(!prefix.equals("xmlns"))
{
String ns = getNamespaceForPrefix(prefix);
+
if((null != ns)
&& ns.equals( m_stylesheet.m_XSLNameSpaceURL ))
{
// process xsl:extension-element-prefixes - Stripped from result
tree
String localName = aname.substring(indexOfNSSep+1);
- if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
- {
+ m_excludeResultPrefixes = processPrefixControl(localName,
atts.getValue(i),
+
m_excludeResultPrefixes);
+ if(null != m_excludeResultPrefixes)
needToProcess = false;
- String qnames = atts.getValue(i);
- StringTokenizer tokenizer = new StringTokenizer(qnames, "
\t\n\r", false);
- m_extensionElementPrefixes = new
String[tokenizer.countTokens()];
- for(int k = 0; tokenizer.hasMoreTokens(); k++)
- {
- m_extensionElementPrefixes[k] = tokenizer.nextToken();
- m_excludeResultPrefixes =
m_stylesheet.processExcludeResultPrefixes(m_extensionElementPrefixes[k], null);
- }
- }
- // process xsl:exclude-result-prefixes - Stripped from result
tree
- else
if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
- {
- needToProcess = false;
- m_excludeResultPrefixes =
m_stylesheet.processExcludeResultPrefixes(atts.getValue(i), null);
- }
// process xsl:version
else if (localName.equals(Constants.ATTRNAME_VERSION))
{
@@ -137,7 +130,11 @@
}
}
}
-
+ else
+ {
+ // don't process namespace decls
+ needToProcess = false;
+ }
}
if(needToProcess)
{
@@ -153,36 +150,12 @@
m_avts.addElement(new AVT(aname, atts.getType(i), atts.getValue(i),
this, m_stylesheet, processor));
}
- }
- }
- }
-
- // Get the next namespace in the ancestor chain.
- private NameSpace getNextNamespace(ElemTemplateElement[] elem, NameSpace
ns)
- {
- if(null != ns)
- ns = ns.m_next;
-
- if(null == ns)
- {
- if(null != elem[0])
- {
- elem[0] = elem[0].m_parentNode;
- while(null != elem[0])
- {
- ns = elem[0].m_namespaces;
- if(null == ns)
- elem[0] = elem[0].m_parentNode;
- else
- break;
- }
- if(null == ns)
- ns = m_stylesheet.m_namespaceDecls;
}
+ removeExcludedPrefixes(m_excludeResultPrefixes);
+
}
- return ns;
}
-
+
/**
* Execute a Literal Result Element.
*/
@@ -222,7 +195,7 @@
}
// Make sure namespace is not in the excluded list then
// add to result tree
- if(nsprefix == null
||!(m_stylesheet.shouldExcludeResultNamespaceNode(this, nsprefix,
stringedValue)))
+ if(nsprefix == null ||!(shouldExcludeResultNamespaceNode(this,
nsprefix, stringedValue)))
{
//processor.m_pendingAttributes.removeAttribute(avt.m_name);
processor.m_pendingAttributes.addAttribute(avt.m_name,
avt.m_type,
@@ -242,4 +215,5 @@
executeChildren(processor, sourceTree, sourceNode, mode);
processor.m_resultTreeHandler.endElement (m_qname);
}
+
}
1.2 +1 -1 xml-xalan/src/org/apache/xalan/xslt/ElemParam.java
Index: ElemParam.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemParam.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ElemParam.java 1999/11/08 20:56:26 1.1
+++ ElemParam.java 2000/02/21 08:14:27 1.2
@@ -99,7 +99,7 @@
java.io.IOException,
SAXException
{
- Object obj = processor.m_variableStacks.getParamVariable(m_qname);
+ Object obj = processor.getVarStack().getParamVariable(m_qname);
if(null == obj)
{
1.19 +311 -267
xml-xalan/src/org/apache/xalan/xslt/ElemTemplateElement.java
Index: ElemTemplateElement.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemTemplateElement.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ElemTemplateElement.java 2000/02/18 16:48:38 1.18
+++ ElemTemplateElement.java 2000/02/21 08:14:27 1.19
@@ -68,6 +68,7 @@
import org.apache.xalan.xslt.res.XSLTErrorResources;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.Serializer;
+import org.apache.xalan.xpath.xml.NameSpace;
/**
* An instance of this class represents an element inside
@@ -114,13 +115,21 @@
public boolean m_defaultSpace = true;
/**
- * The start of a linked list of namespace declarations,
- * for mapping from prefix to namespace URI.
+ * The table of namespaces that can be used in the result
+ * tree.
* @serial
*/
- protected NameSpace m_namespaces = null;
-
+ protected StringToStringTable m_namespaces = null;
+
/**
+ * The table of namespaces that are excluded from being
+ * used in the result tree but which need to be used
+ * in to resolve prefixes.
+ * @serial
+ */
+ protected StringToStringTable m_excludedNamespaces = null;
+
+ /**
* Tell if we've finished construction. This is set to
* false until the endElement is encountered. It's mainly
* used to tell us when we need to use the element tree
@@ -147,7 +156,7 @@
* @serial
*/
ElemTemplateElement m_nextSibling;
-
+
/**
* First child.
* @serial
@@ -178,7 +187,31 @@
m_stylesheet = stylesheetTree;
if(!m_stylesheet.m_namespaces.empty())
{
- m_namespaces =
(org.apache.xalan.xpath.xml.NameSpace)m_stylesheet.m_namespaces.peek();
+ m_namespaces = new StringToStringTable();
+ int n = m_stylesheet.m_namespaces.size();
+ for(int i = (n-1); i >= 0; i--)
+ {
+ NameSpace ns = (NameSpace)m_stylesheet.m_namespaces.elementAt(i);
+ for(;null != ns; ns = ns.m_next)
+ {
+ if(ns == m_stylesheet.m_emptyNamespace)
+ continue;
+
+ if(!m_namespaces.containsValue(ns.m_uri))
+ {
+ if(!shouldExcludeResultNamespaceNode(this, ns.m_prefix,
ns.m_uri))
+ {
+ m_namespaces.put(ns.m_prefix, ns.m_uri);
+ }
+ else
+ {
+ if(null == m_excludedNamespaces)
+ m_excludedNamespaces = new StringToStringTable();
+ m_excludedNamespaces.put(ns.m_prefix, ns.m_uri);
+ }
+ }
+ }
+ }
}
m_baseident = ((URL)m_stylesheet.m_includeStack.peek()).toExternalForm();
//System.out.println("base " + m_baseident);
@@ -233,6 +266,9 @@
public String getNamespaceForPrefix(String prefix)
{
String namespace = null;
+ if(null == prefix)
+ return null;
+
if(m_finishedConstruction)
{
if(null != prefix)
@@ -243,25 +279,12 @@
}
else
{
- ElemTemplateElement elem = this;
- while((null == namespace) && (null != elem))
- {
- org.apache.xalan.xpath.xml.NameSpace ns =
(org.apache.xalan.xpath.xml.NameSpace)elem.m_namespaces;
- while(null != ns)
- {
- if((null != ns.m_prefix) && prefix.equals(ns.m_prefix))
- {
- namespace = ns.m_uri;
- break;
- }
- ns = ns.m_next;
- }
- elem = elem.m_parentNode;
- }
- if(null == namespace)
+ namespace = m_namespaces.get(prefix);
+ if((null == namespace) && (null != m_excludedNamespaces))
{
- namespace = m_stylesheet.getNamespaceForPrefix(prefix);
+ namespace = m_excludedNamespaces.get(prefix);
}
+
}
}
}
@@ -291,6 +314,38 @@
Integer i = (Integer)m_stylesheet.m_attributeKeys.get(name);
return (null == i) ? -2 : i.intValue();
}
+
+ /**
+ * Process the exclude-result-prefixes or the extension-element-prefixes
+ * attributes, for the purpose of prefix exclusion.
+ */
+ protected StringToStringTable processPrefixControl(String localName,
+ String attrValue,
+ StringToStringTable
excludeResultPrefixes)
+ throws SAXException
+ {
+ if(localName.equals(Constants.ATTRNAME_EXTENSIONELEMENTPREFIXES))
+ {
+ String qnames = attrValue;
+ StringTokenizer tokenizer = new StringTokenizer(qnames, " \t\n\r",
false);
+ String extensionElementPrefixes[] = new
String[tokenizer.countTokens()];
+ for(int k = 0; tokenizer.hasMoreTokens(); k++)
+ {
+ String eprefix = tokenizer.nextToken();
+ excludeResultPrefixes
+ = m_stylesheet.processExcludeResultPrefixes(eprefix,
+ excludeResultPrefixes);
+ }
+ }
+ // process xsl:exclude-result-prefixes - Stripped from result tree
+ else if(localName.equals(Constants.ATTRNAME_EXCLUDE_RESULT_PREFIXES))
+ {
+ excludeResultPrefixes
+ = m_stylesheet.processExcludeResultPrefixes(attrValue,
+ excludeResultPrefixes);
+ }
+ return excludeResultPrefixes;
+ }
/**
* See if this is a xmlns attribute, and, if so, process it.
@@ -302,9 +357,11 @@
* @return True if this is a namespace name.
*/
boolean isAttrOK(int tok, String attrName, AttributeList atts, int which)
+ throws SAXException
{
boolean isXMLNS = (Constants.TATTRNAME_XMLNSDEF == tok)
|| attrName.startsWith(Constants.ATTRNAME_XMLNS);
+
// TODO: Well, process it...
return isXMLNS;
}
@@ -319,6 +376,7 @@
* @return True if this attribute should not be flagged as an error.
*/
final boolean isAttrOK(String attrName, AttributeList atts, int which)
+ throws SAXException
{
return m_stylesheet.isAttrOK(attrName, atts, which);
}
@@ -404,7 +462,7 @@
if(XSLTEngineImpl.m_emptyNamespace == nsOnStack)
{
resultNameSpaces.setElementAt(ns,
- resultNameSpaces.size() - 1);
+ resultNameSpaces.size() - 1);
}
else
{
@@ -446,78 +504,95 @@
return true;
}
- // Get the next namespace in the ancestor chain.
- private NameSpace getNextNamespace(ElemTemplateElement[] elem, NameSpace
ns)
+ /**
+ * Remove any excluded prefixes from the current namespaces.
+ */
+ void removeExcludedPrefixes(StringToStringTable excludeResultPrefixes)
{
- if(null != ns)
- ns = ns.m_next;
-
- if(null == ns)
+ if((null != excludeResultPrefixes) && (null != m_namespaces))
{
- if(null != elem[0])
+ int n = excludeResultPrefixes.getLength();
+ for(int k = 0; k < n; k+=2)
{
- elem[0] = elem[0].m_parentNode;
- while(null != elem[0])
+ String p = excludeResultPrefixes.elementAt(k);
+ String url = m_namespaces.get(p);
+ if(null != url)
{
- ns = elem[0].m_namespaces;
- if(null == ns)
- elem[0] = elem[0].m_parentNode;
- else
- break;
+ if(null == m_excludedNamespaces)
+ m_excludedNamespaces = new StringToStringTable();
+ m_excludedNamespaces.put(p, url);
+ m_namespaces.remove(p);
}
- if(null == ns)
- ns = m_stylesheet.m_namespaceDecls;
}
}
- return ns;
}
- /*
- * Decide which namespace declarations to output
+ /**
+ * Tell if the result namespace decl should be excluded. Should be called
before
+ * namespace aliasing (I think).
+ * TODO: I believe this contains a bug, in that included elements will
check with with
+ * their including stylesheet, since in this implementation right now the
included
+ * templates are merged with the including stylesheet. The XSLT
Recommendation says: "The
+ * designation of a namespace as an excluded namespace is effective within
+ * the subtree of the stylesheet rooted at the element bearing the
+ * <code>exclude-result-prefixes</code> or
<code>xsl:exclude-result-prefixes</code>
+ * attribute; a subtree rooted at an <code>xsl:stylesheet</code> element
+ * does not include any stylesheets imported or included by children
+ * of that <code>xsl:stylesheet</code> element."
*/
+ protected boolean shouldExcludeResultNamespaceNode(ElemTemplateElement
elem, String prefix, String uri)
+ throws SAXException
+ {
+ if(uri.equals(m_stylesheet.m_XSLNameSpaceURL)
+ || (null != m_stylesheet.lookupExtensionNSHandler(uri))
+ || uri.equals("http://xml.apache.org/xslt")
+ || uri.equals("http://xsl.lotus.com/")
+ || uri.equals("http://xsl.lotus.com"))
+ return true;
+
+ while(null != elem)
+ {
+ elem = elem.m_parentNode;
+ if(null == elem)
+ {
+ if(null != m_stylesheet.m_excludeResultPrefixes)
+ {
+ if(m_stylesheet.m_excludeResultPrefixes.contains(prefix))
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Decide which namespace declarations to output
+ */
void processResultNS( XSLTEngineImpl processor) throws SAXException
{
- ElemTemplateElement[] elem = processor.m_elemHolder;
- elem[0] = this;
-
- org.apache.xalan.xpath.xml.NameSpace ns =
(NameSpace)elem[0].m_namespaces;
-
- // Handle namespaces(including those on the ancestor chain
- // and stylesheet root declarations).
- if(null == ns)
- ns = getNextNamespace(elem, ns);
+ if(null == m_namespaces)
+ return;
- while(null != ns)
+ int n = m_namespaces.getLength();
+ for(int i = 0; i < n; i+=2)
{
- if(null != ns.m_uri)
+ String prefix = m_namespaces.elementAt(i);
+ String srcURI = m_namespaces.elementAt(i+1);
+ boolean hasPrefix = (prefix != null) && (prefix.length() > 0);
+ if(!hasPrefix)
+ prefix = "";
+ String desturi = processor.getResultNamespaceForPrefix(prefix);
+ String attrName = hasPrefix ? ("xmlns:"+prefix) : "xmlns";
+ // Look for an alias for this URI. If one is found, use it as the
result URI
+ String aliasURI = m_stylesheet.lookForAlias(srcURI);
+ if(!aliasURI.equals(desturi)) // TODO: Check for extension namespaces
{
- boolean hasPrefix = (ns.m_prefix != null) && (ns.m_prefix.length() >
0);
- String prefix = hasPrefix ? ns.m_prefix : "";
- String desturi = processor.getResultNamespaceForPrefix(prefix);
- String attrName = hasPrefix ? ("xmlns:"+prefix) : "xmlns";
- String srcURI = ns.m_uri;
- // Look for an alias for this URI. If one is found, use it as the
result URI
- String aliasURI = m_stylesheet.lookForAlias(srcURI);
- if(!aliasURI.equals(desturi)) // TODO: Check for extension namespaces
- {
- // NOTE: shouldExcludeResultNamespaceNode climbs up the ancestor
- // chain every time. Clearly, this is a performance bottleneck.
- // In general, I think this whole section for handling result
namespaces
- // should have most of this logic figured out at the stylesheet
- // build time (i.e. in the constructor)... how feasible is this?
- if(!m_stylesheet.shouldExcludeResultNamespaceNode(this, prefix,
srcURI))
- {
- addResultAttribute(processor.m_resultNameSpaces,
- processor.m_pendingAttributes,
- attrName, srcURI);
- }
- }
+ addResultAttribute(processor.m_resultNameSpaces,
+ processor.m_pendingAttributes,
+ attrName, srcURI);
}
-
- ns = getNextNamespace(elem, ns);
} // end while
- elem[0] = null;
}
/** Execute the element's primary function. Subclasses of this
@@ -572,18 +647,28 @@
* from xsl:include or xsl:import.
*/
public void executeChildren(XSLTEngineImpl processor,
- Node sourceTree,
- Node sourceNode,
- QName mode)
+ Node sourceTree,
+ Node sourceNode,
+ QName mode)
throws XSLProcessorException,
java.net.MalformedURLException,
java.io.FileNotFoundException,
java.io.IOException,
SAXException
{
- for (ElemTemplateElement node = m_firstChild; node != null; node =
node.m_nextSibling)
+ if(null != m_firstChild)
+ processor.getVarStack().pushElemFrame(this);
+ try
+ {
+ for (ElemTemplateElement node = m_firstChild; node != null; node =
node.m_nextSibling)
+ {
+ node.execute(processor, sourceTree, sourceNode, mode);
+ }
+ }
+ finally
{
- node.execute(processor, sourceTree, sourceNode, mode);
+ if(null != m_firstChild)
+ processor.getVarStack().popElemFrame(this);
}
}
@@ -608,9 +693,9 @@
* @return The stringized result of executing the elements children.
*/
public String childrenToString(XSLTEngineImpl processor,
- Node sourceTree,
- Node sourceNode,
- QName mode)
+ Node sourceTree,
+ Node sourceNode,
+ QName mode)
throws XSLProcessorException,
java.net.MalformedURLException,
java.io.FileNotFoundException,
@@ -657,56 +742,22 @@
return Constants.ELEMNAME_UNDEFINED;
}
- /**
- * Perform a query if needed, and call transformChild for each child.
- *
- * @exception XSLProcessorException Thrown if the active ProblemListener
and
- * XMLParserLiaison decide the error condition is severe enough to
halt
- * processing.
- * @exception java.net.MalformedURLException Might be thrown from the
- * document() function, or from xsl:include or xsl:import.
- * @exception java.io.FileNotFoundException Might be thrown from the
- * document() function, or from xsl:include or xsl:import.
- * @exception java.io.IOException Might be thrown from the document()
- * function, or from xsl:include or xsl:import.
- * @exception SAXException Thrown in a variety of circumstances.
- * @param stylesheetTree The owning stylesheet tree.
- * @param xslInstruction The stylesheet element context (depricated -- I
do
- * not think we need this).
- * @param template The owning template context.
- * @param sourceTree The input source tree.
- * @param sourceNodeContext The current source node context.
- * @param mode The current mode.
- * @param selectPattern The XPath with which to perform the selection.
- * @param xslToken The current XSLT instruction (depricated -- I do not
- * think we want this).
+ /**
+ * Get the keys for the xsl:sort elements.
*/
- protected void transformSelectedChildren(
- Stylesheet stylesheetTree,
- ElemTemplateElement
xslInstruction, // xsl:apply-templates or xsl:for-each
- ElemTemplateElement template, //
The template to copy to the result tree
- Node sourceTree,
- Node sourceNodeContext, QName
mode,
- XPath selectPattern,
- int xslToken,
- XSLTEngineImpl tcontext)
- throws XSLProcessorException,
- java.net.MalformedURLException,
- java.io.FileNotFoundException,
- java.io.IOException,
- SAXException
+ private Vector processSortKeys(ElemTemplateElement xslInstruction,
+ XSLTEngineImpl tcontext, Node
sourceNodeContext)
+ throws SAXException
{
- // Sort the nodes according to the xsl:sort method
- int tok = xslInstruction.getXSLToken();
Vector keys = null;
- NodeCallback callback = this;
+ int tok = xslInstruction.getXSLToken();
if((Constants.ELEMNAME_APPLY_TEMPLATES == tok) ||
(Constants.ELEMNAME_FOREACH == tok))
{
+ XPathSupport execContext = tcontext.getExecContext();
ElemForEach foreach = (ElemForEach)xslInstruction;
if(null != foreach.m_sortElems)
{
- callback = null; // can't use callbacks
int nChildren = foreach.m_sortElems.size();
keys = new Vector();
@@ -714,7 +765,6 @@
for(int i = 0; i < nChildren; i++)
{
ElemSort sort = (ElemSort)foreach.m_sortElems.elementAt(i);
- XPathSupport execContext = tcontext.getExecContext();
String langString = (null != sort.lang_avt)
? sort.lang_avt.evaluate(execContext,
sourceNodeContext, this,
new StringBuffer())
@@ -731,7 +781,7 @@
true : false;
String caseOrderString = sort.caseOrder_avt.evaluate(execContext,
sourceNodeContext, this,
- new
StringBuffer());
+ new
StringBuffer());
boolean caseOrderUpper = ((null != caseOrderString)&&
caseOrderString.equals(Constants.ATTRVAL_CASEORDER_UPPER)) ?
true : false;
@@ -739,10 +789,59 @@
keys.addElement(new NodeSortKey(tcontext, sort.m_selectPattern,
treatAsNumbers,
descending, langString,
-
caseOrderUpper,xslInstruction));
+ caseOrderUpper,xslInstruction));
}
}
}
+ return keys;
+ }
+
+ /**
+ * Perform a query if needed, and call transformChild for each child.
+ *
+ * @exception XSLProcessorException Thrown if the active ProblemListener
and
+ * XMLParserLiaison decide the error condition is severe enough to
halt
+ * processing.
+ * @exception java.net.MalformedURLException Might be thrown from the
+ * document() function, or from xsl:include or xsl:import.
+ * @exception java.io.FileNotFoundException Might be thrown from the
+ * document() function, or from xsl:include or xsl:import.
+ * @exception java.io.IOException Might be thrown from the document()
+ * function, or from xsl:include or xsl:import.
+ * @exception SAXException Thrown in a variety of circumstances.
+ * @param stylesheetTree The owning stylesheet tree.
+ * @param xslInstruction The stylesheet element context (depricated -- I
do
+ * not think we need this).
+ * @param template The owning template context.
+ * @param sourceTree The input source tree.
+ * @param sourceNodeContext The current source node context.
+ * @param mode The current mode.
+ * @param selectPattern The XPath with which to perform the selection.
+ * @param xslToken The current XSLT instruction (depricated -- I do not
+ * think we want this).
+ */
+ protected void transformSelectedChildren(
+ Stylesheet stylesheetTree,
+ ElemTemplateElement
xslInstruction, // xsl:apply-templates or xsl:for-each
+ ElemTemplateElement template, //
The template to copy to the result tree
+ Node sourceTree,
+ Node sourceNodeContext, QName
mode,
+ XPath selectPattern,
+ int xslToken,
+ XSLTEngineImpl tcontext)
+ throws XSLProcessorException,
+ java.net.MalformedURLException,
+ java.io.FileNotFoundException,
+ java.io.IOException,
+ SAXException
+ {
+ // Sort the nodes according to the xsl:sort method
+ int tok = xslInstruction.getXSLToken();
+ Vector keys = processSortKeys(xslInstruction,
+ tcontext, sourceNodeContext);
+
+ // We can only do callbacks if the node list isn't sorted.
+ NodeCallback callback = (null == keys) ? this : null;
NodeList sourceNodes = null;
if(null != selectPattern)
@@ -764,13 +863,7 @@
XObject result = selectPattern.execute(execContext, sourceNodeContext,
xslInstruction, callback,
callbackContext, false);
- if(null != result)
- {
- sourceNodes = result.nodeset();
-
- if(sourceNodes.getLength() == 0)
- sourceNodes = null;
- }
+ sourceNodes = result.nodeset();
if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
{
@@ -786,6 +879,8 @@
}
else if(null != keys)
{
+ // In this case just add the children to a nodelist for sorting, as if
+ // a selection took place.
MutableNodeListImpl msourceNodes = new MutableNodeListImpl();
for(Node child=sourceNodeContext.getFirstChild(); null != child;
child=child.getNextSibling())
{
@@ -793,10 +888,10 @@
}
sourceNodes = msourceNodes;
}
-
+
if(null != sourceNodes)
{
- int nNodes = (null != sourceNodes) ? sourceNodes.getLength() : 0;
+ int nNodes = sourceNodes.getLength();
if(nNodes > 0)
{
@@ -815,18 +910,9 @@
for(int i = 0; i < nNodes; i++)
{
- Node childNode = sourceNodes.item(i);
-
- Document ownerDoc = childNode.getOwnerDocument();
- if((Node.DOCUMENT_NODE != childNode.getNodeType()) && (null ==
ownerDoc))
- {
- error(XSLTErrorResources.ER_NO_OWNERDOC, null); //"Child node
does not have an owner document!");
- }
-
transformChild(
stylesheetTree, xslInstruction, template,
- ownerDoc,
- sourceNodeContext, childNode,
+ sourceNodeContext, sourceNodes.item(i),
mode, xslToken, tcontext);
}
}
@@ -852,15 +938,9 @@
for(Node childNode = sourceNodeContext.getFirstChild();
null != childNode; childNode = childNode.getNextSibling())
{
- if(childNode.getNodeType() == Node.TEXT_NODE)
- {
- if(tcontext.shouldStripSourceNode(childNode))
- continue;
- }
contextNodeList.addNode(childNode);
transformChild(
stylesheetTree, xslInstruction, template,
- ownerDoc,
sourceNodeContext, childNode,
mode, xslToken, tcontext);
}
@@ -917,8 +997,8 @@
* @param callbackInfo Opaque info for the caller's benefit.
*/
public void processLocatedNode(XPathSupport execContext,
- Node sourceNode,
- Object callbackInfo)
+ Node sourceNode,
+ Object callbackInfo)
throws SAXException
{
TemplateElementContext templateContext =
(TemplateElementContext)callbackInfo;
@@ -928,7 +1008,6 @@
transformChild(templateContext.m_stylesheetTree,
templateContext.m_xslInstruction, //
xsl:apply-templates or xsl:for-each
templateContext.m_template, // may be null
- sourceNode.getOwnerDocument(),
templateContext.m_sourceNodeContext,
sourceNode,
templateContext.m_mode,
@@ -951,11 +1030,11 @@
/*
catch(Exception mue)
{
- throw new XSLProcessorException(mue);
+ throw new XSLProcessorException(mue);
}
*/
}
-
+
/**
* Given an element and mode, find the corresponding
* template and process the contents.
@@ -982,7 +1061,6 @@
boolean transformChild(Stylesheet stylesheetTree,
ElemTemplateElement xslInstruction, //
xsl:apply-templates or xsl:for-each
ElemTemplateElement template, // may be null
- Node sourceTree,
Node selectContext,
Node child,
QName mode, int xslToken,
@@ -993,125 +1071,80 @@
java.io.FileNotFoundException,
java.io.IOException,
SAXException
- {
- boolean doApplyTemplate = true; // return value
-
- boolean shouldStrip = false;
+ {
int nodeType = child.getNodeType();
-
- boolean isApplyImports = (xslToken == Constants.ELEMNAME_APPLY_IMPORTS);
- if(!shouldStrip)
+ Node sourceTree = (Node.DOCUMENT_NODE == nodeType) ? child :
child.getOwnerDocument();
+
+ if(null == template)
{
+ boolean isApplyImports = (xslToken ==
Constants.ELEMNAME_APPLY_IMPORTS);
+ if(!isApplyImports)
+ stylesheetTree = m_stylesheet.m_stylesheetRoot;
+
+ // Find the XSL template that is the best match for the
+ // element.
+ template = stylesheetTree.findTemplate(transformContext, sourceTree,
child, mode,
+ isApplyImports);
if(null == template)
{
- // Find the XSL template that is the best match for the
- // element, and call buildResultFromTemplate.
- Stylesheet[] foundStylesheet =
transformContext.m_foundStylesheet;
- foundStylesheet[0] = null;
-
- if(!isApplyImports)
+ switch(nodeType)
{
- stylesheetTree = m_stylesheet.m_stylesheetRoot;
- }
- template = stylesheetTree.findTemplate(transformContext, sourceTree,
child, mode,
- isApplyImports,
foundStylesheet);
-
- if(isApplyImports && (null != template))
- {
- stylesheetTree = foundStylesheet[0];
- }
- // mode = null; // non-sticky modes
-
- foundStylesheet[0] = null;
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ case Node.ELEMENT_NODE:
+ template = m_stylesheet.m_stylesheetRoot.m_defaultRule;
+ break;
+ case Node.CDATA_SECTION_NODE:
+ case Node.TEXT_NODE:
+ case Node.ATTRIBUTE_NODE:
+ template = m_stylesheet.m_stylesheetRoot.m_defaultTextRule;
+ break;
+ case Node.DOCUMENT_NODE:
+ template = m_stylesheet.m_stylesheetRoot.m_defaultRootRule;
+ break;
+ }
}
-
- if(doApplyTemplate)
+ }
+
+ if(null != template)
+ {
+ transformContext.resetCurrentState(child);
+
+ if(template == m_stylesheet.m_stylesheetRoot.m_defaultTextRule)
{
- if(null == template)
+ switch(nodeType)
{
- switch(nodeType)
- {
- case Node.DOCUMENT_FRAGMENT_NODE:
- case Node.ELEMENT_NODE:
- template = m_stylesheet.m_stylesheetRoot.m_defaultRule;
- break;
- case Node.CDATA_SECTION_NODE:
- case Node.TEXT_NODE:
- case Node.ATTRIBUTE_NODE:
- template = m_stylesheet.m_stylesheetRoot.m_defaultTextRule;
- break;
- case Node.DOCUMENT_NODE:
- template = m_stylesheet.m_stylesheetRoot.m_defaultRootRule;
- break;
- }
- if(null != template)
+ case Node.CDATA_SECTION_NODE:
+ case Node.TEXT_NODE:
+ transformContext.cloneToResultTree(stylesheetTree, child, false,
false, false);
+ break;
+ case Node.ATTRIBUTE_NODE:
{
- stylesheetTree = m_stylesheet.m_stylesheetRoot; // Not sure if
this is needed. -sb
+ Attr attr = (Attr)child;
+ String val = attr.getValue();
+
transformContext.m_resultTreeHandler.characters(val.toCharArray(), 0,
val.length());
}
+ break;
}
-
- if(null != template)
+ }
+ else
+ {
+ if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
{
- transformContext.resetCurrentState(sourceTree, child);
-
- if(template == m_stylesheet.m_stylesheetRoot.m_defaultTextRule)
- {
- switch(nodeType)
- {
- case Node.CDATA_SECTION_NODE:
- case Node.TEXT_NODE:
- transformContext.cloneToResultTree(stylesheetTree, child,
false, false, false);
- break;
- case Node.ATTRIBUTE_NODE:
- {
- Attr attr = (Attr)child;
- String val = attr.getValue();
-
transformContext.m_resultTreeHandler.characters(val.toCharArray(), 0,
val.length());
- }
- break;
- }
- }
- else
- {
- boolean doPush = (xslToken != Constants.ELEMNAME_FOREACH);
- if(doPush)
- {
- transformContext.m_variableStacks.pushContextMarker(template,
child);
-
- if(null != xslInstruction)
- {
-
transformContext.m_variableStacks.pushParams(transformContext.getExecContext(),
- stylesheetTree,
- xslInstruction,
- sourceTree,
- selectContext,
mode, template);
- }
- }
-
- if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
- {
- TracerEvent te = new TracerEvent(transformContext,
- sourceTree,
- child,
- mode,
- template);
- m_stylesheet.m_stylesheetRoot.fireTraceEvent(te);
- }
- template.executeChildren(transformContext, sourceTree, child,
mode);
-
- if(doPush)
- {
- transformContext.m_variableStacks.popCurrentContext();
- }
- }
-
- transformContext.resetCurrentState(sourceTree, selectContext);
+ TracerEvent te = new TracerEvent(transformContext,
+ sourceTree,
+ child,
+ mode,
+ template);
+ m_stylesheet.m_stylesheetRoot.fireTraceEvent(te);
}
+ template.executeChildren(transformContext, sourceTree, child, mode);
}
+
+ transformContext.resetCurrentState(selectContext);
}
- return doApplyTemplate;
+ return true;
}
-
+
/**
* Throw a template element runtime error. (Note: should we throw a
SAXException instead?)
*
@@ -1119,8 +1152,8 @@
*/
public void error(int msg, Object[] args)
{
- String themsg = XSLMessages.createMessage(msg, args);
- throw new
RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
new Object[] {themsg})); //"ElemTemplateElement error: "+msg);
+ String themsg = XSLMessages.createMessage(msg, args);
+ throw new
RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ELEMTEMPLATEELEM_ERR,
new Object[] {themsg})); //"ElemTemplateElement error: "+msg);
}
// Implemented DOM Element methods.
@@ -1149,6 +1182,17 @@
last.m_nextSibling = elem;
}
elem.m_parentNode = this;
+
+ // Do exclusion of result attributes
+ for(ElemTemplateElement parent = this; parent != null; parent =
parent.m_parentNode)
+ {
+ int tok = parent.getXSLToken();
+ if((tok == Constants.ELEMNAME_LITERALRESULT) || (tok ==
Constants.ELEMNAME_EXTENSIONCALL))
+ {
+
elem.removeExcludedPrefixes(((ElemLiteralResult)parent).m_excludeResultPrefixes);
+ }
+ }
+
return newChild;
}
@@ -1283,4 +1327,4 @@
public Object get(Object obj){return null; }
}
- }
+}
1.4 +3 -4 xml-xalan/src/org/apache/xalan/xslt/ElemVariable.java
Index: ElemVariable.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/ElemVariable.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ElemVariable.java 2000/01/05 23:05:32 1.3
+++ ElemVariable.java 2000/02/21 08:14:27 1.4
@@ -140,7 +140,7 @@
super.execute(processor, sourceTree, sourceNode, mode);
// System.out.println("Calling getValue for variable named:
"+m_qname.m_localpart);
XObject var = getValue(processor, sourceTree, sourceNode);
- processor.m_variableStacks.pushVariable(m_qname, var, getParentNode());
+ processor.getVarStack().pushVariable(m_qname, var);
}
/**
@@ -156,11 +156,10 @@
SAXException
{
XObject var;
- XPathSupport execContext = processor.getXMLProcessorLiaison();
if(null != m_selectPattern)
{
- var = m_selectPattern.execute(processor.getExecContext(),
- sourceNode, this);
+ XPathSupport execContext = processor.getXMLProcessorLiaison();
+ var = m_selectPattern.execute(execContext, sourceNode, this);
if(null != m_stylesheet.m_stylesheetRoot.m_traceListeners)
{
m_stylesheet.m_stylesheetRoot.fireSelectedEvent(new
SelectionEvent(processor,
1.6 +2 -2
xml-xalan/src/org/apache/xalan/xslt/ExtensionNSHandler.java
Index: ExtensionNSHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/ExtensionNSHandler.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ExtensionNSHandler.java 2000/02/17 13:06:26 1.5
+++ ExtensionNSHandler.java 2000/02/21 08:14:27 1.6
@@ -229,7 +229,7 @@
XSLTEngineImpl processor,
Stylesheet stylesheetTree,
Node sourceTree, Node sourceNode, QName mode,
- Class classObj)
+ Class classObj, Object methodKey)
throws XSLProcessorException,
MalformedURLException,
FileNotFoundException,
@@ -258,7 +258,7 @@
Vector argv = new Vector (2);
argv.addElement (xpc);
argv.addElement (element);
- result = super.callFunction (localPart, argv, this, classObj);
+ result = super.callFunction (localPart, argv, methodKey, classObj);
}
catch (XPathProcessorException e)
{
1.28 +7 -63 xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java
Index: Stylesheet.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/Stylesheet.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- Stylesheet.java 2000/02/13 19:40:14 1.27
+++ Stylesheet.java 2000/02/21 08:14:27 1.28
@@ -342,7 +342,8 @@
* Process the exclude-result-prefixes attribute or
xsl:exclude-result-prefixes
* attribute.
*/
- StringToStringTable processExcludeResultPrefixes(String val,
StringToStringTable excludeResultPrefixes)
+ StringToStringTable processExcludeResultPrefixes(String val,
+ StringToStringTable
excludeResultPrefixes)
throws SAXException
{
if(null == excludeResultPrefixes)
@@ -364,62 +365,6 @@
}
/**
- * Tell if the result namespace decl should be excluded. Should be called
before
- * namespace aliasing (I think).
- * TODO: I believe this contains a bug, in that included elements will
check with with
- * their including stylesheet, since in this implementation right now the
included
- * templates are merged with the including stylesheet. The XSLT
Recommendation says: "The
- * designation of a namespace as an excluded namespace is effective within
- * the subtree of the stylesheet rooted at the element bearing the
- * <code>exclude-result-prefixes</code> or
<code>xsl:exclude-result-prefixes</code>
- * attribute; a subtree rooted at an <code>xsl:stylesheet</code> element
- * does not include any stylesheets imported or included by children
- * of that <code>xsl:stylesheet</code> element."
- */
- boolean shouldExcludeResultNamespaceNode(ElemTemplateElement elem, String
prefix, String uri)
- throws SAXException
- {
- if(uri.equals(m_XSLNameSpaceURL)
- || (null != lookupExtensionNSHandler(uri))
- || uri.equals("http://xml.apache.org/xslt")
- || uri.equals("http://xsl.lotus.com/")
- || uri.equals("http://xsl.lotus.com"))
- return true;
-
- while(null != elem)
- {
- if(Constants.ELEMNAME_LITERALRESULT == elem.getXSLToken())
- {
- StringToStringTable t =
((ElemLiteralResult)elem).m_excludeResultPrefixes;
- if(null != t)
- {
- if(t.contains(prefix))
- return true;
- }
- }
- else if(Constants.ELEMNAME_EXTENSIONCALL == elem.getXSLToken())
- {
- StringToStringTable t =
((ElemExtensionCall)elem).m_excludeResultPrefixes;
- if(null != t)
- {
- if(t.contains(prefix))
- return true;
- }
- }
- elem = elem.m_parentNode;
- if(null == elem)
- {
- if(null != m_excludeResultPrefixes)
- {
- if(m_excludeResultPrefixes.contains(prefix))
- return true;
- }
- }
- }
- return false;
- }
-
- /**
* Table for defined constants, keyed on the names.
* @serial
*/
@@ -464,7 +409,7 @@
* xmlns attribute is found.
* @serial
*/
- private final org.apache.xalan.xpath.xml.NameSpace m_emptyNamespace
+ final org.apache.xalan.xpath.xml.NameSpace m_emptyNamespace
= new org.apache.xalan.xpath.xml.NameSpace(null, null);
/**
@@ -1016,7 +961,7 @@
transformContext.m_rootDoc,
this);
a.m_expression = null;
}
- transformContext.m_variableStacks.pushVariable(a.m_qname,
a.m_val, this);
+ transformContext.getVarStack().pushVariable(a.m_qname,
a.m_val);
break;
}
}
@@ -1055,7 +1000,7 @@
java.io.FileNotFoundException,
java.io.IOException
{
- return getTemplateList().findTemplate(transformContext, sourceTree,
targetNode, null, false, null);
+ return getTemplateList().findTemplate(transformContext, sourceTree,
targetNode, null, false);
}
/**
@@ -1077,13 +1022,12 @@
Node sourceTree,
Node targetNode,
QName mode,
- boolean useImports,
- Stylesheet foundStylesheet[])
+ boolean useImports)
throws SAXException
{
return getTemplateList().findTemplate(transformContext,
sourceTree, targetNode,
- mode, useImports, foundStylesheet);
+ mode, useImports);
}
/**
1.23 +5 -3
xml-xalan/src/org/apache/xalan/xslt/StylesheetHandler.java
Index: StylesheetHandler.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/StylesheetHandler.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- StylesheetHandler.java 2000/02/18 18:10:30 1.22
+++ StylesheetHandler.java 2000/02/21 08:14:27 1.23
@@ -938,8 +938,10 @@
ExtensionNSHandler nsh = m_stylesheet.lookupExtensionNSHandler
(extns);
if (nsh == null)
{
- if (elements != null)
- throw new SAXException
(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_EXT_NS_PREFIX, new
Object[]{name, prefix})); //"(StylesheetHandler) " + name +
+ // xsl:extension-element-prefixes might not be known yet,
+ // see extend17.xsl.
+ // if (elements != null)
+ // throw new SAXException
(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_EXT_NS_PREFIX, new
Object[]{name, prefix})); //"(StylesheetHandler) " + name +
if (null == extns)
extns = "";
@@ -1086,7 +1088,7 @@
}
else if(Constants.ELEMNAME_LITERALRESULT == tok)
- {
+ {
ElemLiteralResult extcall = (ElemLiteralResult)parent;
extensionElementPrefixes =
extcall.m_extensionElementPrefixes;
}
1.26 +2 -2 xml-xalan/src/org/apache/xalan/xslt/StylesheetRoot.java
Index: StylesheetRoot.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/StylesheetRoot.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- StylesheetRoot.java 2000/02/18 04:17:45 1.25
+++ StylesheetRoot.java 2000/02/21 08:14:28 1.26
@@ -400,7 +400,7 @@
processor.m_flistener = new
FormatterToDOM((Document)outputTarget.getNode());
}
- processor.resetCurrentState(sourceTree, sourceTree);
+ processor.resetCurrentState(sourceTree);
processor.m_rootDoc = sourceTree;
if(null != processor.m_diagnosticsPrintWriter)
@@ -410,7 +410,7 @@
processor.pushTime(sourceTree);
}
- processor.m_variableStacks.pushContextMarker(null, null);
+ processor.getVarStack().pushContextMarker();
try
{
processor.resolveTopLevelParams();
1.4 +2 -10 xml-xalan/src/org/apache/xalan/xslt/TemplateList.java
Index: TemplateList.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/TemplateList.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TemplateList.java 2000/02/09 20:11:11 1.3
+++ TemplateList.java 2000/02/21 08:14:28 1.4
@@ -202,8 +202,6 @@
* @param targetElem The element that needs a rule.
* @param mode A string indicating the display mode.
* @param useImports means that this is an xsl:apply-imports commend.
- * @param foundStylesheet If non-null, the Stylesheet that the found
template
- * belongs to will be returned in the foundStylesheet[0].
* @return Rule that best matches targetElem.
* @exception XSLProcessorException thrown if the active ProblemListener
and XMLParserLiaison decide
* the error condition is severe enough to halt processing.
@@ -212,8 +210,7 @@
Node sourceTree,
Node targetNode,
QName mode,
- boolean useImports,
- Stylesheet foundStylesheet[])
+ boolean useImports)
throws SAXException
{
ElemTemplate bestMatchedRule = null;
@@ -356,7 +353,7 @@
{
Stylesheet stylesheet =
(Stylesheet)m_stylesheet.m_imports.elementAt(i);
bestMatchedRule = stylesheet.findTemplate(transformContext,
sourceTree, targetNode, mode,
- false, foundStylesheet);
+ false);
if(null != bestMatchedRule)
{
break;
@@ -400,11 +397,6 @@
}
}
- if((null != bestMatchedPattern) && (null != foundStylesheet))
- {
- foundStylesheet[0] = bestMatchedPattern.m_stylesheet;
- }
-
return bestMatchedRule;
} // end findTemplate
1.42 +20 -370 xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java
Index: XSLTEngineImpl.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xslt/XSLTEngineImpl.java,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- XSLTEngineImpl.java 2000/02/18 16:48:38 1.41
+++ XSLTEngineImpl.java 2000/02/21 08:14:28 1.42
@@ -291,7 +291,13 @@
* The stack of Variable stacks. A VariableStack will be
* pushed onto this stack for each template invocation.
*/
- VariableStack m_variableStacks = new VariableStack();
+ private VariableStack m_variableStacks = new VariableStack();
+
+ /**
+ * Get the variable stack, which is in charge of variables and
+ * parameters.
+ */
+ final VariableStack getVarStack() { return m_variableStacks; }
/**
* If true, output carriage returns.
@@ -347,16 +353,6 @@
transient Stack m_attrSetStack = null;
/**
- * Used as an in/out variable
- */
- transient final Stylesheet m_foundStylesheet[] = new Stylesheet[1];
-
- /**
- * Used as an in/out variable
- */
- transient final ElemTemplateElement[] m_elemHolder = new
ElemTemplateElement[1];
-
- /**
* The table of counters for xsl:number support.
* @see ElemNumber
*/
@@ -1988,7 +1984,7 @@
AttributeList atts;
if(shouldCloneAttributes)
{
- copyAttributesToAttList( node, m_stylesheetRoot, (Element)node,
m_pendingAttributes );
+ copyAttributesToAttList( (Element)node, m_stylesheetRoot,
m_pendingAttributes );
copySourceNSAttrs(node, m_pendingAttributes);
}
m_resultTreeHandler.startElement (node.getNodeName());
@@ -2425,16 +2421,15 @@
* @exception XSLProcessorException thrown if the active ProblemListener
and XMLParserLiaison decide
* the error condition is severe enough to halt processing.
*/
- protected void copyAttributesToAttList(
- Node contextNode,
+ protected void copyAttributesToAttList(Element contextNode,
Stylesheet stylesheetTree,
- Element templateChild,
MutableAttrListImpl attList)
+ MutableAttrListImpl attList)
throws SAXException,
java.net.MalformedURLException,
java.io.FileNotFoundException,
java.io.IOException
{
- NamedNodeMap attributes = templateChild.getAttributes();
+ NamedNodeMap attributes = contextNode.getAttributes();
int nAttributes = (null != attributes) ? attributes.getLength() : 0;
String attrSetUseVal = null;
for(int i = 0; i < nAttributes; i++)
@@ -2447,7 +2442,7 @@
else
{
copyAttributeToTarget( attr, contextNode, stylesheetTree,
- attList, templateChild);
+ attList, contextNode);
}
} // end for(long i = 0; i < nAttributes; i++)
@@ -2673,8 +2668,9 @@
public boolean shouldStripSourceNode(Node textNode)
throws org.xml.sax.SAXException
{
- if((null != m_stylesheetRoot.m_whitespacePreservingElements) ||
- (null != m_stylesheetRoot.m_whitespaceStrippingElements)
+ if((null != m_stylesheetRoot) &&
+ ((null != m_stylesheetRoot.m_whitespacePreservingElements) ||
+ (null != m_stylesheetRoot.m_whitespaceStrippingElements))
)
{
boolean strip = false; // return value
@@ -2701,6 +2697,7 @@
{
Element parentElem = (Element)parent;
+ /*
Attr attr = parentElem.getAttributeNode("xml:space");
if(null != attr)
{
@@ -2720,6 +2717,7 @@
}
break;
}
+ */
double highPreserveScore = XPath.MATCH_SCORE_NONE;
double highStripScore = XPath.MATCH_SCORE_NONE;
@@ -3136,13 +3134,7 @@
public XObject getVariable(QName qname)
throws org.xml.sax.SAXException
{
- Object obj = m_variableStacks.getVariable(qname);
- /*
- if(null == obj)
- {
- obj = m_stylesheetRoot.getTopLevelVariable(qname, m_rootDoc);
- }
- */
+ Object obj = getVarStack().getVariable(qname);
if((null != obj) && !(obj instanceof XObject))
{
obj = new XObject(obj);
@@ -3296,15 +3288,9 @@
/**
* Reset the current element state
*/
- protected void resetCurrentState(Node sourceTree, Node xmlNode)
+ protected final void resetCurrentState(Node xmlNode)
{
- if(null != xmlNode)
- {
- //===============================================
- // This will be used with callbacks from script,
- // in places like getAttributeCallback.
- m_currentNode = xmlNode;
- }
+ m_currentNode = xmlNode;
}
@@ -3751,342 +3737,6 @@
}
} // end StackGuard class
-
- /**
- * This class marks where a macro call context ends. Only
- * calls above this marker at the top of the stack can
- * be reached with getVariable(String name).
- */
- class ContextState
- {
- Node m_caller;
- Node m_source;
- ContextState(Node caller, Node sourceNode)
- {
- m_caller = caller;
- m_source = sourceNode;
- }
- }
-
- /**
- * This class marks where a call context ends. Only
- * calls above this marker at the top of the stack can
- * be reached with getVariable(String name).
- */
- class ContextMarker extends ContextState
- {
- ContextMarker(Node caller, Node sourceNode)
- {
- super(caller, sourceNode);
- }
- }
-
- class ElementMarker
- {
- Node m_elem;
- ElementMarker(Node elem)
- {
- m_elem = elem;
- }
- }
-
- /**
- * Defines a class to keep track of a stack for
- * macro arguments.
- */
- class VariableStack extends Stack
- {
- /**
- * Holds caller, so that it may be searched for
- * xsl:params, in order to resolve xsl:param-arg.
- */
- Element m_caller;
-
- /**
- * Constructor for a variable stack.
- */
- VariableStack()
- {
- pushContextMarker(null, null);
- }
-
- // Push a context marker onto the stack to let us know when
- // to stop searching for a var.
- void pushElementMarker(Node elem)
- {
- push(new ElementMarker(elem));
- }
-
- /**
- * Pop the current context from the current context stack.
- */
- void popElementMarker(Node elem)
- {
- if(elementMarkerAlreadyPushed(elem))
- {
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof ElementMarker)
- {
- pop();
- break;
- }
- else
- {
- pop();
- }
- }
- }
- }
-
- /**
- * Pop the current context from the current context stack.
- */
- boolean elementMarkerAlreadyPushed(Node elem)
- {
- boolean alreadyPushed = false;
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof ElementMarker)
- {
- if(((ElementMarker)obj).m_elem == elem)
- {
- alreadyPushed = true;
- }
- break;
- }
- }
- return alreadyPushed;
- }
-
-
- // Push a context marker onto the stack to let us know when
- // to stop searching for a var.
- void pushContextMarker(Node caller, Node sourceNode)
- {
- push(new ContextMarker(caller, sourceNode));
- }
-
- /**
- * Pop the current context from the current context stack.
- */
- void popCurrentContext()
- {
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = this.peek();
- if(obj instanceof ContextMarker)
- {
- pop();
- break;
- }
- else
- {
- pop();
- }
- }
- }
-
- /**
- * Given a template, search for
- * the arguments and push them on the stack. Also,
- * push default arguments on the stack.
- * You <em>must</em> call popContext() when you are
- * done with the arguments.
- */
- void pushParams(XPathSupport execContext,
- Stylesheet stylesheetTree,
- ElemTemplateElement xslCallTemplateElement,
- Node sourceTree,
- Node sourceNode, QName mode, Node targetTemplate)
- throws SAXException,
- java.net.MalformedURLException,
- java.io.FileNotFoundException,
- java.io.IOException,
- SAXException
- {
- Stack tempStack = new Stack();
- ContextMarker cm = (ContextMarker)pop();
- ElemTemplateElement child =
(ElemTemplateElement)xslCallTemplateElement.getFirstChild();
- while(null != child)
- {
- if(Constants.ELEMNAME_WITHPARAM == child.getXSLToken())
- {
- ElemWithParam xslParamElement = (ElemWithParam)child;
-
- XObject var;
- if(null != xslParamElement.m_selectPattern)
- {
- var = xslParamElement.m_selectPattern.execute(execContext,
sourceNode,
- xslParamElement);
- }
- else
- {
- // Use result tree fragment
- DocumentFragment df = createResultTreeFrag(stylesheetTree,
xslParamElement,
- sourceTree,
sourceNode, mode);
- var = new XRTreeFrag(df);
- }
- Arg arg = new Arg(xslParamElement.m_qname, var, true);
- tempStack.push(arg);
- }
- child = child.m_nextSibling;
- } // end for m
-
- push(cm);
- pushElementMarker(targetTemplate);
-
- int nParams = tempStack.size();
- for(int i = 0; i < nParams; i++)
- {
- push(tempStack.elementAt(i));
- }
-
- } // end pushParams method
-
- /**
- * Tell if there is a param variable on the stack.
- */
- boolean hasParamVariable(QName qname)
- throws SAXException
- {
- boolean hasit = false;
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof Arg)
- {
- if(((Arg)obj).equals(qname))
- {
- hasit = true;
- break;
- }
- }
- else if(obj instanceof ContextMarker)
- {
- break;
- }
- }
- return hasit;
- }
-
-
- /**
- * Same as getVariable, except don't look in the
- * global space.
- */
- XObject getParamVariable(QName qname)
- throws SAXException
- {
- XObject val = null;
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof Arg)
- {
- if(((Arg)obj).equals(qname))
- {
- val = ((Arg)obj).m_val;
- break;
- }
- }
- else if(obj instanceof ContextMarker)
- {
- break;
- }
- }
- return val;
- }
-
-
- /**
- * Given a name, return a string representing
- * the value.
- */
- Object getVariable(QName name)
- throws SAXException
- {
- Object val = null;
- int nElems = size();
- // Sub 1 extra for the context marker.
- for(int i = (nElems - 1); i >= 0; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof Arg)
- {
- if(((Arg)obj).equals(name))
- {
- val = ((Arg)obj).m_val;
- break;
- }
- }
- else if(obj instanceof ContextMarker)
- {
- break;
- }
- }
- if(null == val)
- {
- int i;
- // Find the start of the global
- for(i = 2; i < (nElems - 1); i++)
- {
- Object obj = elementAt(i);
- if(obj instanceof ContextMarker)
- {
- break;
- }
- }
-
- // Look in the global space
- for(i--; i >= 2; i--)
- {
- Object obj = elementAt(i);
- if(obj instanceof Arg)
- {
- if(((Arg)obj).equals(name))
- {
- val = ((Arg)obj).m_val;
- break;
- }
- }
- else if(obj instanceof ContextMarker)
- {
- break;
- }
- }
- }
- return val;
- }
-
- /**
- * Push an argument onto the stack. Don't forget
- * to call startContext before pushing a series of
- * arguments for a given macro call.
- */
- void pushVariable(QName qname, XObject val, Node e)
- {
- if(!elementMarkerAlreadyPushed(e))
- {
- pushElementMarker(e);
- }
- Arg arg = new Arg(qname, val, false);
- push(arg);
- }
-
- } // end XSLArgStack
/**
* Bottleneck addition of result tree attributes, so I can keep
1.1 xml-xalan/src/org/apache/xalan/xslt/VariableStack.java
Index: VariableStack.java
===================================================================
package org.apache.xalan.xslt;
import java.util.Stack;
import java.util.Vector;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.DocumentFragment;
import org.xml.sax.SAXException;
import org.apache.xalan.xpath.XPathSupport;
import org.apache.xalan.xpath.xml.QName;
import org.apache.xalan.xpath.XObject;
import org.apache.xalan.xpath.XRTreeFrag;
/**
* Defines a class to keep track of a stack for
* template arguments and variables, since we can't
* simply bind the variables to templates and walk
* the preceding children and ancestors. The stack
* is delimited by context markers which bound call
* frames, and which you can't search past for a variable,
* and by element frames, which are Arg objects with
* the given ElemTemplateElement instead of a qname. You
* can search past element frames, and they accumulate
* until they are popped.
*/
class VariableStack extends Stack
{
private static final Integer contextMarker = new Integer(0);
private Vector m_paramsTemp = new Vector();
private static final Arg m_elemFrameBoundry = new Arg();
/**
* Constructor for a variable stack.
*/
VariableStack()
{
pushContextMarker();
}
// Push a context marker onto the stack to let us know when
// to stop searching for a var.
void pushContextMarker()
{
push(contextMarker);
}
/**
* Pop the current context from the current context stack.
*/
void popCurrentContext()
{
int nElems = size();
// Sub 1 extra for the context marker.
for(int i = (nElems - 1); i >= 0; i--)
{
if(this.elementAt(i) == contextMarker)
{
this.setSize(i);
break;
}
}
}
/**
* Given a template, search for
* the arguments and push them on the stack. Also,
* push default arguments on the stack.
* You <em>must</em> call popContext() when you are
* done with the arguments.
*/
void pushParams(XSLTEngineImpl engine,
Stylesheet stylesheetTree,
ElemTemplateElement xslCallTemplateElement,
Node sourceTree,
Node sourceNode, QName mode)
throws SAXException,
java.net.MalformedURLException,
java.io.FileNotFoundException,
java.io.IOException,
SAXException
{
// The trick here is, variables need to be executed outside the context
// of the current stack frame.
for(ElemTemplateElement child =
(ElemTemplateElement)xslCallTemplateElement.getFirstChild();
null != child; child = child.m_nextSibling)
{
if(Constants.ELEMNAME_WITHPARAM == child.getXSLToken())
{
ElemWithParam xslParamElement = (ElemWithParam)child;
XObject var;
if(null != xslParamElement.m_selectPattern)
{
var =
xslParamElement.m_selectPattern.execute(engine.getXMLProcessorLiaison(),
sourceNode,
xslParamElement);
}
else
{
// Use result tree fragment
DocumentFragment df = engine.createResultTreeFrag(stylesheetTree,
xslParamElement,
sourceTree,
sourceNode, mode);
var = new XRTreeFrag(df);
}
m_paramsTemp.addElement(new Arg(xslParamElement.m_qname, var, true));
}
}
push(this.contextMarker); // push the context marker for the next stack
frame
// Now push all the found parameters on to the stack.
int n = m_paramsTemp.size();
if(n > 0)
{
for(int i = 0; i < n; i++)
this.push(m_paramsTemp.elementAt(i));
m_paramsTemp.removeAllElements();
}
} // end pushParams method
/**
* Same as getVariable, except don't look in the
* global space.
*/
public XObject getParamVariable(QName qname)
throws SAXException
{
XObject val = null;
int nElems = size();
// Sub 1 extra for the context marker.
for(int i = (nElems - 1); i >= 0; i--)
{
Object obj = elementAt(i);
if(obj == contextMarker)
{
break;
}
else if(((Arg)obj).equals(qname))
{
val = ((Arg)obj).m_val;
break;
}
}
return val;
}
/**
* Given a name, return a string representing
* the value.
*/
public Object getVariable(QName name)
throws SAXException
{
int nElems = size();
// Sub 1 extra for the context marker.
for(int i = (nElems - 1); i >= 0; i--)
{
Object obj = elementAt(i);
if(obj == contextMarker)
{
break;
}
else if(((Arg)obj).equals(name))
{
return ((Arg)obj).m_val;
}
}
int i;
// Find the start of the global
for(i = 2; i < (nElems - 1); i++)
{
Object obj = elementAt(i);
// If there is a context marker or a element frame, the
// we found the start of the global stack frame.
if((obj == contextMarker) || (obj == m_elemFrameBoundry))
break;
}
// Look in the global space
for(i--; i >= 2; i--)
{
Object obj = elementAt(i);
if(obj == contextMarker)
break;
else if(((Arg)obj).equals(name))
return ((Arg)obj).m_val;
}
return null;
}
/**
* Push an argument onto the stack. Don't forget
* to call startContext before pushing a series of
* arguments for a given macro call.
*/
public void pushVariable(QName qname, XObject val)
{
push(new Arg(qname, val, false));
}
/**
* Push an argument onto the stack. Don't forget
* to call startContext before pushing a series of
* arguments for a given macro call.
*/
public void pushElemFrame(ElemTemplateElement elem)
{
push(m_elemFrameBoundry);
}
/**
* Pop the current context from the current context stack.
*/
void popElemFrame(ElemTemplateElement elem)
{
int nElems = size();
// Sub 1 extra for the context marker.
for(int i = (nElems - 1); i >= 0; i--)
{
Object obj = this.elementAt(i);
if(obj == contextMarker)
{
break;
}
else if(obj == m_elemFrameBoundry)
{
this.setSize(i);
break;
}
}
}
} // end XSLArgStack
1.7 +6 -5
xml-xalan/src/org/apache/xalan/xslt/extensions/Redirect.java
Index: Redirect.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xslt/extensions/Redirect.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Redirect.java 2000/01/20 15:04:40 1.6
+++ Redirect.java 2000/02/21 08:14:30 1.7
@@ -64,6 +64,7 @@
import org.apache.xalan.xslt.res.XSLTErrorResources;
import org.apache.xalan.xpath.XObject;
import org.apache.xalan.xslt.StylesheetRoot;
+import org.apache.xalan.xslt.ElemExtensionCall;
import java.io.*;
import java.net.URL;
import org.apache.xalan.xpath.xml.*;
@@ -162,7 +163,7 @@
Object flistener = m_formatterListeners.get(fileName);
if(null == flistener)
{
- String mkdirsExpr = elem.getAttribute ("mkdirs");
+ String mkdirsExpr = ((ElemExtensionCall)elem).getAttribute ("mkdirs",
context.sourceNode, context.processor);
boolean mkdirs = (mkdirsExpr != null)
? (mkdirsExpr.equals("true") ||
mkdirsExpr.equals("yes")) : true;
DocumentHandler fl = makeFormatterListener(context, fileName, true,
mkdirs);
@@ -187,7 +188,7 @@
boolean inTable = false;
if(null == flObject)
{
- String mkdirsExpr = elem.getAttribute ("mkdirs");
+ String mkdirsExpr = ((ElemExtensionCall)elem).getAttribute ("mkdirs",
context.sourceNode, context.processor);
boolean mkdirs = (mkdirsExpr != null)
? (mkdirsExpr.equals("true") ||
mkdirsExpr.equals("yes")) : true;
formatter = makeFormatterListener(context, fileName, true, mkdirs);
@@ -251,7 +252,7 @@
org.xml.sax.SAXException
{
String fileName;
- String fileNameExpr = elem.getAttribute ("select");
+ String fileNameExpr = ((ElemExtensionCall)elem).getAttribute ("select",
context.sourceNode, context.processor);
if(null != fileNameExpr)
{
org.apache.xalan.xpath.XPathSupport execContext =
context.processor.getExecContext();
@@ -261,12 +262,12 @@
fileName = xobj.str();
if((null == fileName) || (fileName.length() == 0))
{
- fileName = elem.getAttribute ("file");
+ fileName = ((ElemExtensionCall)elem).getAttribute ("file",
context.sourceNode, context.processor);
}
}
else
{
- fileName = elem.getAttribute ("file");
+ fileName = ((ElemExtensionCall)elem).getAttribute ("file",
context.sourceNode, context.processor);
}
if(null == fileName)
{