Implement default templates using code rather then inserting them in the xslt-document DOM. bug 86270. r=peterv sr=jst a=asa (for drivers)

Also fix soon-to-be bustage from 72810 landing
This commit is contained in:
sicking%bigfoot.com 2001-06-20 07:07:14 +00:00
parent d2c83623ea
commit e2b7bd7a31
4 changed files with 89 additions and 72 deletions

View File

@ -30,7 +30,7 @@
/**
* Implementation of ProcessorState
* Much of this code was ported from XSL:P
* @version $Revision: 1.30 $ $Date: 2001/06/20 06:00:35 $
* @version $Revision: 1.31 $ $Date: 2001/06/20 07:07:09 $
**/
#include "ProcessorState.h"
@ -84,10 +84,6 @@ ProcessorState::ProcessorState(Document& xslDocument, Document& resultDocument)
**/
ProcessorState::~ProcessorState() {
if (dfWildCardTemplate)
delete dfWildCardTemplate;
if (dfTextTemplate)
delete dfTextTemplate;
delete resultNodeStack;
while ( ! variableSets.empty() ) {
@ -920,9 +916,6 @@ ProcessorState::XMLSpaceMode ProcessorState::getXMLSpaceMode(Node* node) {
* Initializes this ProcessorState
**/
void ProcessorState::initialize() {
dfWildCardTemplate = 0;
dfTextTemplate = 0;
//-- initialize default-space
defaultSpace = PRESERVE;
@ -1004,44 +997,8 @@ void ProcessorState::initialize() {
} //-- end for each att
} //-- end if atts are not null
/* Create default (built-in) templates */
//-- create default template for elements
String templateName = xsltNameSpace;
if (templateName.length() > 0) templateName.append(':');
templateName.append(TEMPLATE);
String actionName = xsltNameSpace;
if ( actionName.length()>0) actionName.append(':');
actionName.append(APPLY_TEMPLATES);
dfWildCardTemplate = xslDocument->createElement(templateName);
dfWildCardTemplate->setAttribute(MATCH_ATTR, "* | /");
dfWildCardTemplate->appendChild(xslDocument->createElement(actionName));
templates.add(dfWildCardTemplate);
//-- create default "built-in" templates for text nodes
dfTextTemplate = xslDocument->createElement(templateName);
dfTextTemplate->setAttribute(MATCH_ATTR, "text()|@*");
actionName = xsltNameSpace;
if ( actionName.length()>0) actionName.append(':');
actionName.append(VALUE_OF);
Element* value_of = xslDocument->createElement(actionName);
value_of->setAttribute(SELECT_ATTR, IDENTITY_OP);
dfTextTemplate->appendChild(value_of);
templates.add(dfTextTemplate);
String wild("*");
//-- add PatternExpr hash for default templates
patternExprHash.put("*", new ElementExpr(wild));
patternExprHash.put("/", new RootExpr());
patternExprHash.put("text()", new TextExpr());
//cout << "XSLT namespace: " << xsltNameSpace << endl;
}
//-- Make sure all loaded documents get deleted
loadedDocuments.setObjectDeletion(MB_TRUE);
}

View File

@ -21,7 +21,7 @@
* Keith Visco, kvisco@ziplink.net
* -- original author.
*
* $Id: ProcessorState.h,v 1.13 2001/04/12 14:04:52 peterv%netscape.com Exp $
* $Id: ProcessorState.h,v 1.14 2001/06/20 07:07:11 sicking%bigfoot.com Exp $
*/
@ -43,7 +43,7 @@
/**
* Class used for keeping the current state of the XSL Processor
* @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
* @version $Revision: 1.13 $ $Date: 2001/04/12 14:04:52 $
* @version $Revision: 1.14 $ $Date: 2001/06/20 07:07:11 $
**/
class ProcessorState : public ContextState {
@ -415,10 +415,6 @@ private:
Stack defaultNameSpaceURIStack;
Stack xsltNameSpaces;
//-- default templates
Element* dfWildCardTemplate;
Element* dfTextTemplate;
/**
* Returns the closest xml:space value for the given node
**/

View File

@ -72,7 +72,7 @@
/**
* XSLTProcessor is a class for Processing XSL stylesheets
* @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
* @version $Revision: 1.56 $ $Date: 2001/06/20 07:02:30 $
* @version $Revision: 1.57 $ $Date: 2001/06/20 07:07:11 $
**/
/**
@ -624,8 +624,8 @@ void XSLTProcessor::process
NodeSet nodeSet;
nodeSet.add(&xmlDocument);
ps->pushCurrentNode(&xmlDocument);
ps->getNodeSetStack()->push(&nodeSet);
ps.pushCurrentNode(&xmlDocument);
ps.getNodeSetStack()->push(&nodeSet);
//-------------------------------------------------------/
//- index templates and process top level xsl elements -/
@ -856,8 +856,10 @@ void XSLTProcessor::process(Node* node, Node* context, ProcessorState* ps) {
void XSLTProcessor::process(Node* node, Node* context, String* mode, ProcessorState* ps) {
if ( !node ) return;
Element* xslTemplate = ps->findTemplate(node, context, mode);
if (!xslTemplate) return;
processTemplate(node, xslTemplate, ps);
if (xslTemplate)
processTemplate(node, xslTemplate, ps);
else
processDefaultTemplate(node, ps, NULL);
} //-- process
void XSLTProcessor::processAction
@ -949,11 +951,13 @@ void XSLTProcessor::processAction
ps->getNodeSetStack()->push(nodeSet);
for (int i = 0; i < nodeSet->size(); i++) {
Element* xslTemplate = ps->findTemplate(nodeSet->get(i), node, mode);
if ( xslTemplate ) {
if (xslTemplate) {
NamedMap* actualParams = processParameters(actionElement, node, ps);
processTemplate(nodeSet->get(i), xslTemplate, ps, actualParams);
delete actualParams;
}
else
processDefaultTemplate(nodeSet->get(i), ps, mode);
}
//-- remove nodeSet from context stack
ps->getNodeSetStack()->pop();
@ -1577,24 +1581,76 @@ void XSLTProcessor::processChildren(Node* node, Element* xslElement, ProcessorSt
**/
void XSLTProcessor::processTemplate(Node* node, Node* xslTemplate, ProcessorState* ps, NamedMap* params) {
if ( !xslTemplate ) {
//-- do default?
}
else {
Stack* bindings = ps->getVariableSetStack();
NamedMap localBindings;
localBindings.setObjectDeletion(MB_TRUE);
bindings->push(&localBindings);
processTemplateParams(xslTemplate, node, ps, params);
Node* tmp = xslTemplate->getFirstChild();
while (tmp) {
processAction(node,tmp,ps);
tmp = tmp->getNextSibling();
}
bindings->pop();
NS_ASSERTION(xslTemplate, "xslTemplate is NULL in call to XSLTProcessor::processTemplate!");
Stack* bindings = ps->getVariableSetStack();
NamedMap localBindings;
localBindings.setObjectDeletion(MB_TRUE);
bindings->push(&localBindings);
processTemplateParams(xslTemplate, node, ps, params);
Node* tmp = xslTemplate->getFirstChild();
while (tmp) {
processAction(node,tmp,ps);
tmp = tmp->getNextSibling();
}
bindings->pop();
} //-- processTemplate
/**
* Invokes the default template for the specified node
* @param node context node
* @param ps current ProcessorState
* @param mode template mode
**/
void XSLTProcessor::processDefaultTemplate(Node* node, ProcessorState* ps, String* mode)
{
NS_ASSERTION(node, "context node is NULL in call to XSLTProcessor::processTemplate!");
switch(node->getNodeType())
{
case Node::ELEMENT_NODE :
case Node::DOCUMENT_NODE :
{
Expr* expr = ps->getPatternExpr("node()");
ExprResult* exprResult = expr->evaluate(node, ps);
if ( exprResult->getResultType() != ExprResult::NODESET ) {
notifyError("None-nodeset returned while processing default template");
delete exprResult;
return;
}
NodeSet* nodeSet = (NodeSet*)exprResult;
//-- make sure nodes are in DocumentOrder
//-- this isn't strictly neccecary with the current XPath engine
ps->sortByDocumentOrder(nodeSet);
//-- push nodeSet onto context stack
ps->getNodeSetStack()->push(nodeSet);
for (int i = 0; i < nodeSet->size(); i++) {
Element* xslTemplate = ps->findTemplate(nodeSet->get(i), node, mode);
if (xslTemplate)
processTemplate(nodeSet->get(i), xslTemplate, ps, NULL);
else
processDefaultTemplate(nodeSet->get(i), ps, mode);
}
//-- remove nodeSet from context stack
ps->getNodeSetStack()->pop();
delete exprResult;
break;
}
case Node::ATTRIBUTE_NODE :
case Node::TEXT_NODE :
case Node::CDATA_SECTION_NODE :
ps->addToResultTree(ps->getResultDocument()->createTextNode(node->getNodeValue()));
break;
default:
// on all other nodetypes (including namespace nodes)
// we do nothing
break;
}
} //-- processDefaultTemplate
/**
* Builds the initial bindings for the template. Formal parameters (xsl:param) that
* have a corresponding binding in actualParams are bound to the actual parameter value,

View File

@ -62,7 +62,7 @@
/**
* A class for Processing XSL Stylesheets
* @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
* @version $Revision: 1.22 $ $Date: 2001/06/20 06:46:12 $
* @version $Revision: 1.23 $ $Date: 2001/06/20 07:07:14 $
**/
class XSLTProcessor
#ifndef TX_EXE
@ -337,6 +337,14 @@ private:
void processTemplate(Node* node, Node* xslTemplate, ProcessorState* ps, NamedMap* actualParams = NULL);
void processTemplateParams(Node* xslTemplate, Node* context, ProcessorState* ps, NamedMap* actualParams);
/**
* Invokes the default template for the specified node
* @param node context node
* @param ps current ProcessorState
* @param mode template mode
**/
void processDefaultTemplate(Node* node, ProcessorState* ps, String* mode);
void processTopLevel(Document* aSource, Document* aStylesheet, ProcessorState* aPs);
void processTopLevel(Document* aSource, Element* aStylesheet, ProcessorState* aPs);