dbertoni 00/05/15 08:57:48
Modified: c/src/XSLT ElemApplyTemplates.cpp ElemCallTemplate.cpp
ElemTemplateElement.cpp
StylesheetExecutionContext.cpp
StylesheetExecutionContext.hpp XSLTEngineImpl.cpp
XSLTEngineImpl.hpp
Log:
Fixed bugs in variable handling and source node stripping.
Revision Changes Path
1.6 +12 -19 xml-xalan/c/src/XSLT/ElemApplyTemplates.cpp
Index: ElemApplyTemplates.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemApplyTemplates.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElemApplyTemplates.cpp 2000/04/12 19:40:56 1.5
+++ ElemApplyTemplates.cpp 2000/05/15 15:57:44 1.6
@@ -144,22 +144,19 @@
}
if (0 != sourceNode)
{
- ElemTemplateElement* const theTemplate =
- const_cast<ElemTemplateElement* const>
- (static_cast<const ElemTemplateElement*
const>(this));
-
// Dragons here. Push the params & stack frame, but then
execute the
// select statement inside transformSelectedChildren, which
must be
// executed in the stack frame before the new stack frame.
Because of
// depth-first searching, this gets worse.
- int selectStackFrameIndex =
executionContext.getCurrentStackFrameIndex();
- executionContext.pushContextMarker(theTemplate,
- sourceNode);
-
executionContext.setCurrentStackFrameIndex(selectStackFrameIndex);
- executionContext.pushParams(*this, sourceTree, sourceNode, mode,
- theTemplate);
+ StylesheetExecutionContext::ParamsPushPop thePushPop(
+ executionContext,
+ this,
+ *this,
+ sourceTree,
+ sourceNode,
+ mode,
+ this);
- executionContext.setCurrentStackFrameIndex();
transformSelectedChildren(
executionContext,
getStylesheet(),
@@ -170,11 +167,7 @@
m_isDefaultTemplate == false ? m_mode : mode,
m_pSelectPattern,
Constants::ELEMNAME_APPLY_TEMPLATES,
- selectStackFrameIndex);
-
- executionContext.popCurrentContext();
-
executionContext.setCurrentStackFrameIndex(selectStackFrameIndex);
-
+ thePushPop.getStackFrameIndex());
}
else
{
@@ -188,7 +181,7 @@
ElemApplyTemplates::childTypeAllowed(int xslToken) const
{
bool fResult = false;
-
+
switch(xslToken)
{
// char-instructions
@@ -196,10 +189,10 @@
case Constants::ELEMNAME_WITHPARAM:
fResult = true;
break;
-
+
default:
break;
}
-
+
return fResult;
}
1.6 +9 -12 xml-xalan/c/src/XSLT/ElemCallTemplate.cpp
Index: ElemCallTemplate.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemCallTemplate.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElemCallTemplate.cpp 2000/04/20 15:07:40 1.5
+++ ElemCallTemplate.cpp 2000/05/15 15:57:45 1.6
@@ -98,7 +98,7 @@
if(equals(aname, Constants::ATTRNAME_NAME))
{
- m_templateName = new QName(atts.getValue(i),
getStylesheet().getNamespaces());
+ m_templateName = new QName(atts.getValue(i),
getStylesheet().getNamespaces());
/*
m_pNameAVT = new AVT(aname, atts.getType(i),
atts.getValue(i),
@@ -138,19 +138,16 @@
if(0 != theTemplate)
{
- int selectStackFrameIndex =
executionContext.getCurrentStackFrameIndex();
- executionContext.pushContextMarker(theTemplate,
- sourceNode);
-
executionContext.setCurrentStackFrameIndex(selectStackFrameIndex);
- executionContext.pushParams(*this, sourceTree,
sourceNode, mode,
- theTemplate);
- executionContext.markGlobalStackFrame();
+ StylesheetExecutionContext::ParamsPushPop
thePushPop(
+ executionContext,
+ theTemplate,
+ *this,
+ sourceTree,
+ sourceNode,
+ mode,
+ theTemplate);
- executionContext.setCurrentStackFrameIndex();
theTemplate->execute(executionContext, sourceTree,
sourceNode, mode);
-
- executionContext.popCurrentContext();
-
executionContext.setCurrentStackFrameIndex(selectStackFrameIndex);
}
else
{
1.19 +1 -21 xml-xalan/c/src/XSLT/ElemTemplateElement.cpp
Index: ElemTemplateElement.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemTemplateElement.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ElemTemplateElement.cpp 2000/05/03 19:06:03 1.18
+++ ElemTemplateElement.cpp 2000/05/15 15:57:45 1.19
@@ -837,22 +837,6 @@
}
else
{
- bool doPush = (xslToken !=
Constants::ELEMNAME_FOREACH);
-
- if(doPush)
- {
-
executionContext.pushContextMarker(theTemplate, child);
-
- if (xslInstruction != 0)
- {
-
executionContext.pushParams(*xslInstruction,
-
sourceTree,
-
selectContext,
-
mode,
-
theTemplate);
- }
- }
-
if(0 !=
getStylesheet().getStylesheetRoot().getTraceListeners())
{
TracerEvent te(executionContext,
@@ -863,15 +847,11 @@
getStylesheet().getStylesheetRoot().fireTraceEvent(te);
}
+
theTemplate->executeChildren(executionContext,
sourceTree,
child,
mode);
-
- if(doPush)
- {
-
executionContext.popCurrentContext();
- }
}
executionContext.resetCurrentState(sourceTree,
selectContext);
1.3 +42 -0 xml-xalan/c/src/XSLT/StylesheetExecutionContext.cpp
Index: StylesheetExecutionContext.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContext.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- StylesheetExecutionContext.cpp 2000/04/20 16:47:35 1.2
+++ StylesheetExecutionContext.cpp 2000/05/15 15:57:45 1.3
@@ -59,6 +59,10 @@
+#include "ElemTemplateElement.hpp"
+
+
+
StylesheetExecutionContext::StylesheetExecutionContext() :
XPathExecutionContext()
{
@@ -68,4 +72,42 @@
StylesheetExecutionContext::~StylesheetExecutionContext()
{
+}
+
+
+
+StylesheetExecutionContext::ParamsPushPop::ParamsPushPop(
+ StylesheetExecutionContext&
executionContext,
+ const ElemTemplateElement* contextElement,
+ const ElemTemplateElement&
xslCallTemplateElement,
+ XalanNode*
sourceTree,
+ XalanNode*
sourceNode,
+ const QName& mode,
+ const XalanNode*
targetTemplate) :
+ m_executionContext(executionContext),
+ m_savedStackFrameIndex(executionContext.getCurrentStackFrameIndex())
+{
+ executionContext.pushContextMarker(
+ contextElement,
+ sourceNode);
+
+ executionContext.setCurrentStackFrameIndex(m_savedStackFrameIndex);
+
+ executionContext.pushParams(
+ xslCallTemplateElement,
+ sourceTree,
+ sourceNode,
+ mode,
+ targetTemplate);
+
+ executionContext.setCurrentStackFrameIndex();
+}
+
+
+
+StylesheetExecutionContext::ParamsPushPop::~ParamsPushPop()
+{
+ m_executionContext.popCurrentContext();
+
+ m_executionContext.setCurrentStackFrameIndex(m_savedStackFrameIndex);
}
1.13 +30 -5 xml-xalan/c/src/XSLT/StylesheetExecutionContext.hpp
Index: StylesheetExecutionContext.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContext.hpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- StylesheetExecutionContext.hpp 2000/05/11 19:06:44 1.12
+++ StylesheetExecutionContext.hpp 2000/05/15 15:57:45 1.13
@@ -629,11 +629,36 @@
virtual void
setCurrentStackFrameIndex(int currentStackFrameIndex = -1) = 0;
- /**
- * Mark the top of the global stack where global searches should start.
+ /*
+ * A class to manage stack state during execution.
*/
- virtual void
- markGlobalStackFrame() = 0;
+ class ParamsPushPop
+ {
+ public:
+
+ ParamsPushPop(
+ StylesheetExecutionContext&
executionContext,
+ const ElemTemplateElement* contextElement,
+ const ElemTemplateElement&
xslCallTemplateElement,
+ XalanNode*
sourceTree,
+ XalanNode*
sourceNode,
+ const QName& mode,
+ const XalanNode*
targetTemplate);
+
+ ~ParamsPushPop();
+
+ int
+ getStackFrameIndex() const
+ {
+ return m_savedStackFrameIndex;
+ }
+
+ private:
+
+ StylesheetExecutionContext& m_executionContext;
+
+ const int
m_savedStackFrameIndex;
+ };
/**
* Receive notification of the beginning of a document.
@@ -1058,7 +1083,7 @@
const XalanDocument& theDocument) const = 0;
virtual bool
- shouldStripSourceNode(const XalanNode& node) const = 0;
+ shouldStripSourceNode(const XalanNode& node) = 0;
virtual bool
getThrowFoundIndex() const = 0;
1.37 +107 -112 xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp
Index: XSLTEngineImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- XSLTEngineImpl.cpp 2000/05/12 18:21:33 1.36
+++ XSLTEngineImpl.cpp 2000/05/15 15:57:45 1.37
@@ -208,7 +208,6 @@
m_variableStacks(*this),
m_problemListener(new ProblemListenerDefault()),
m_stylesheetRoot(0),
- m_stylesheetExecutionContext(0),
m_XSLDirectiveLookup(),
m_quietConflictWarnings(false),
m_traceTemplateChildren(false),
@@ -274,8 +273,6 @@
m_xpathEnvSupport.reset();
m_xpathFactory.reset();
m_xobjectFactory.reset();
-
- m_stylesheetExecutionContext = 0;
}
@@ -2590,7 +2587,6 @@
-
XalanDOMString
XSLTEngineImpl::evaluateAttrVal(
XalanNode* contextNode,
@@ -2857,143 +2853,141 @@
bool
-XSLTEngineImpl::shouldStripSourceNode(const XalanNode& textNode) const
+XSLTEngineImpl::shouldStripSourceNode(
+ XPathExecutionContext& executionContext,
+ const XalanNode& textNode) const
{
- bool strip = false; // return value
- int type = textNode.getNodeType();
- if((XalanNode::TEXT_NODE == type) || (XalanNode::CDATA_SECTION_NODE ==
type))
- {
- const XalanText& theTextNode =
- static_cast<const XalanText&>(textNode);
+ assert(m_stylesheetRoot != 0);
+
+ bool strip = false; // return value
- if(!m_xpathSupport.isIgnorableWhitespace(theTextNode))
+ if((m_stylesheetRoot->getWhitespacePreservingElements().size() > 0 ||
+ m_stylesheetRoot->getWhitespaceStrippingElements().size() > 0))
+ {
+ const XalanNode::NodeType type = textNode.getNodeType();
+ if((XalanNode::TEXT_NODE == type) ||
(XalanNode::CDATA_SECTION_NODE == type))
{
- XalanDOMString data = theTextNode.getData();
- if(0 == length(data))
- {
- return true;
- }
- else if(!isWhiteSpace(data))
+ const XalanText& theTextNode =
+ static_cast<const XalanText&>(textNode);
+
+ if(!m_xpathSupport.isIgnorableWhitespace(theTextNode))
{
- return false;
+ const XalanDOMString data =
theTextNode.getData();
+
+ if(0 == length(data))
+ {
+ return true;
+ }
+ else if(!isWhiteSpace(data))
+ {
+ return false;
+ }
}
- }
- XalanNode* parent =
m_xpathSupport.getParentOfNode(textNode);
+ XalanNode* parent =
m_xpathSupport.getParentOfNode(textNode);
- while(0 != parent)
- {
- if(parent->getNodeType() == XalanNode::ELEMENT_NODE)
+ while(0 != parent)
{
- const XalanElement* const parentElem =
- static_cast<const
XalanElement*>(parent);
-
- const XalanAttr* const attr =
-
parentElem->getAttributeNode(XALAN_STATIC_UCODE_STRING("xml:space"));
-
- if(0 != attr)
+ if(parent->getNodeType() ==
XalanNode::ELEMENT_NODE)
{
- const XalanDOMString xmlSpaceVal =
attr->getValue();
+ const XalanElement* const
parentElem =
+ static_cast<const
XalanElement*>(parent);
- if(equals(xmlSpaceVal,
XALAN_STATIC_UCODE_STRING("preserve")))
- {
- strip = false;
- }
- else if(equals(xmlSpaceVal,
XALAN_STATIC_UCODE_STRING("default")))
- {
- strip = true;
- }
- else
+ /*
+ const XalanAttr* const attr =
+
parentElem->getAttributeNode(XALAN_STATIC_UCODE_STRING("xml:space"));
+
+ if(0 != attr)
{
- error("xml:space in the source
XML has an illegal value: " + xmlSpaceVal);
- }
- break;
- }
+ const XalanDOMString
xmlSpaceVal = attr->getValue();
- double highPreserveScore =
XPath::s_MatchScoreNone;
- double highStripScore = XPath::s_MatchScoreNone;
+ if(equals(xmlSpaceVal,
XALAN_STATIC_UCODE_STRING("preserve")))
+ {
+ strip = false;
+ }
+ else if(equals(xmlSpaceVal,
XALAN_STATIC_UCODE_STRING("default")))
+ {
+ strip = true;
+ }
+ else
+ {
+ error("xml:space in the
source XML has an illegal value: " + xmlSpaceVal);
+ }
+ break;
+ }
+ */
- ElementPrefixResolverProxy
theProxy(parentElem, m_xpathEnvSupport, m_xpathSupport);
+ double highPreserveScore =
XPath::s_MatchScoreNone;
+ double highStripScore =
XPath::s_MatchScoreNone;
- {
- // $$$ ToDo: All of this should be
moved into a member of
- // Stylesheet, so as not to expose
these two data members...
- typedef Stylesheet::XPathVectorType
XPathVectorType;
+ ElementPrefixResolverProxy
theProxy(parentElem, m_xpathEnvSupport, m_xpathSupport);
- const XPathVectorType& theElements =
-
m_stylesheetRoot->getWhitespacePreservingElements();
+ {
+ // $$$ ToDo: All of this
should be moved into a member of
+ // Stylesheet, so as not to
expose these two data members...
+ typedef
Stylesheet::XPathVectorType XPathVectorType;
- const XPathVectorType::size_type
nTests =
- theElements.size();
+ const XPathVectorType&
theElements =
+
m_stylesheetRoot->getWhitespacePreservingElements();
- XPathExecutionContextDefault
theExecutionContext(m_xpathEnvSupport,
-
m_xpathSupport,
-
m_xobjectFactory,
-
parent,
-
NodeRefList(),
-
&theProxy);
+ const
XPathVectorType::size_type nTests =
+ theElements.size();
- for(XPathVectorType::size_type i = 0; i
< nTests; i++)
- {
- const XPath* const
matchPat = theElements[i];
- assert(matchPat != 0);
+ for(XPathVectorType::size_type
i = 0; i < nTests; i++)
+ {
+ const XPath* const
matchPat = theElements[i];
+ assert(matchPat != 0);
- const double score =
matchPat->getMatchScore(parent, theProxy, theExecutionContext);
+ const double score =
matchPat->getMatchScore(parent, theProxy, executionContext);
- if(score > highPreserveScore)
- highPreserveScore =
score;
+ if(score >
highPreserveScore)
+
highPreserveScore = score;
+ }
}
- }
- {
- typedef Stylesheet::XPathVectorType
XPathVectorType;
-
- const XPathVectorType& theElements =
-
m_stylesheetRoot->getWhitespaceStrippingElements();
+ {
+ typedef
Stylesheet::XPathVectorType XPathVectorType;
- const XPathVectorType::size_type
nTests =
- theElements.size();
+ const XPathVectorType&
theElements =
+
m_stylesheetRoot->getWhitespaceStrippingElements();
- XPathExecutionContextDefault
theExecutionContext(m_xpathEnvSupport,
-
m_xpathSupport,
-
m_xobjectFactory,
-
parent,
-
NodeRefList(),
-
&theProxy);
+ const
XPathVectorType::size_type nTests =
+ theElements.size();
- for(XPathVectorType::size_type i = 0; i
< nTests; i++)
- {
- const XPath* const
matchPat =
- theElements[i];
- assert(matchPat != 0);
+ for(XPathVectorType::size_type
i = 0; i < nTests; i++)
+ {
+ const XPath* const
matchPat =
+ theElements[i];
+ assert(matchPat != 0);
- const double score =
matchPat->getMatchScore(parent, theProxy, theExecutionContext);
+ const double score =
matchPat->getMatchScore(parent, theProxy, executionContext);
- if(score > highStripScore)
- highStripScore = score;
+ if(score >
highStripScore)
+ highStripScore
= score;
+ }
}
- }
- if((highPreserveScore >
XPath::s_MatchScoreNone) ||
- (highStripScore > XPath::s_MatchScoreNone))
- {
- if(highPreserveScore > highStripScore)
+ if(highPreserveScore >
XPath::s_MatchScoreNone ||
+ highStripScore >
XPath::s_MatchScoreNone)
{
- strip = false;
- }
- else if(highStripScore >
highPreserveScore)
- {
- strip = true;
- }
- else
- {
- warn("Match conflict between
xsl:strip-space and xsl:preserve-space");
+ if(highPreserveScore >
highStripScore)
+ {
+ strip = false;
+ }
+ else if(highStripScore >
highPreserveScore)
+ {
+ strip = true;
+ }
+ else
+ {
+ warn("Match conflict
between xsl:strip-space and xsl:preserve-space");
+ }
+ break;
}
- break;
}
- }
- parent = parent->getParentNode();
+ parent = parent->getParentNode();
+ }
}
}
@@ -3227,16 +3221,17 @@
XObject*
-XSLTEngineImpl::getXObjectVariable(const XalanDOMString& name) const
+XSLTEngineImpl::getXObjectVariable(
+ StylesheetExecutionContext&
executionContext,
+ const XalanDOMString& name) const
{
assert(m_stylesheetRoot != 0);
- assert(m_stylesheetExecutionContext != 0);
XObject* theResult = m_variableStacks.getXObjectVariable(name);
if(0 == theResult)
{
- theResult = m_stylesheetRoot->getTopLevelVariable(name,
*m_stylesheetExecutionContext);
+ theResult = m_stylesheetRoot->getTopLevelVariable(name,
executionContext);
}
return theResult;
@@ -3393,8 +3388,8 @@
XSLTEngineImpl::resolveTopLevelParams(StylesheetExecutionContext&
executionContext)
{
m_stylesheetRoot->pushTopLevelVariables(executionContext,
m_topLevelParams);
+
getVariableStacks().markGlobalStackFrame();
- getVariableStacks().pushContextMarker(0, 0);
}
1.30 +12 -16 xml-xalan/c/src/XSLT/XSLTEngineImpl.hpp
Index: XSLTEngineImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTEngineImpl.hpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- XSLTEngineImpl.hpp 2000/05/12 18:21:34 1.29
+++ XSLTEngineImpl.hpp 2000/05/15 15:57:45 1.30
@@ -343,18 +343,10 @@
const XalanDOMString& key,
XObject* value);
- /**
- * Tells, through the combination of the default-space attribute on
- * xsl:stylesheet, xsl:strip-space, xsl:preserve-space, and the
xml:space
- * attribute, whether or not extra whitespace should be stripped from
the
- * node. Literal elements from template elements should <em>not</em> be
- * tested with this function.
- *
- * @param textNode text node from the source tree
- * @return true if the text node should be stripped of extra whitespace
- */
virtual bool
- shouldStripSourceNode(const XalanNode& textNode) const;
+ shouldStripSourceNode(
+ XPathExecutionContext& executionContext,
+ const XalanNode& node) const;
virtual FormatterListener*
getFormatterListener() const;
@@ -1590,6 +1582,8 @@
markGlobalStackFrame()
{
m_globalStackFrameIndex = m_stack.size();
+
+ pushContextMarker(0, 0);
}
/**
@@ -1987,8 +1981,6 @@
*/
StylesheetRoot* m_stylesheetRoot;
- StylesheetExecutionContext* m_stylesheetExecutionContext;
-
/**
* The namespace that we must match as a minimum for XSLT.
*/
@@ -2149,11 +2141,15 @@
/**
* Given a name, locate a variable in the current context, and return
* the XObject.
- * @exception XSLProcessorException thrown if the active
ProblemListener and XMLParserLiaison decide
- * the error condition is severe enough to halt processing.
+ *
+ * @param executionContext The current execution context.
+ * @param name The name of the variable
+ * @return a pointer to an XObject that represents the variable.
*/
XObject*
- getXObjectVariable(const XalanDOMString& name) const;
+ getXObjectVariable(
+ StylesheetExecutionContext&
executionContext,
+ const XalanDOMString& name) const;
/**
* Get an XLocator provider keyed by node. This gets the
association