dbertoni 01/07/08 11:41:22
Modified: c/src/XSLT ElemCopyOf.cpp ElemCopyOf.hpp
Log:
More efficient implementation for select="."
Revision Changes Path
1.18 +127 -77 xml-xalan/c/src/XSLT/ElemCopyOf.cpp
Index: ElemCopyOf.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemCopyOf.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- ElemCopyOf.cpp 2001/05/02 15:55:45 1.17
+++ ElemCopyOf.cpp 2001/07/08 18:41:21 1.18
@@ -89,23 +89,37 @@
lineNumber,
columnNumber,
Constants::ELEMNAME_COPY_OF),
- m_pSelectPattern(0)
+ m_selectPattern(0),
+ m_isDot(false)
{
const unsigned int nAttrs = atts.getLength();
- for(unsigned int i = 0; i < nAttrs; i++)
+ for(unsigned int i = 0; i < nAttrs; ++i)
{
const XalanDOMChar* const aname = atts.getName(i);
if(equals(aname, Constants::ATTRNAME_SELECT))
{
- m_pSelectPattern =
constructionContext.createXPath(atts.getValue(i), *this);
+ const XalanDOMChar* const avalue =
atts.getValue(i);
+ assert(avalue != 0);
+
+ if (avalue[0] == XalanUnicode::charFullStop &&
avalue[1] == 0)
+ {
+ m_isDot = true;
+ }
+
+ m_selectPattern =
constructionContext.createXPath(avalue, *this);
}
else if(!isAttrOK(aname, atts, i, constructionContext))
{
-
constructionContext.error(Constants::ELEMNAME_COPY_OF_WITH_PREFIX_STRING + "
has an illegal attribute: " + aname);
+ constructionContext.error(XalanDOMString("xsl:copy-of
has an illegal attribute: ") + aname);
}
}
+
+ if (m_selectPattern == 0)
+ {
+ constructionContext.error("xsl:copy-of must have a \"select\"
attribute.");
+ }
}
@@ -118,107 +132,143 @@
-void
-ElemCopyOf::execute(StylesheetExecutionContext&
executionContext) const
+inline void
+ElemCopyOf::cloneNodeSet(
+ StylesheetExecutionContext&
executionContext,
+ const NodeRefListBase& theNodeList)
const
{
- ElemTemplateElement::execute(executionContext);
-
- assert(m_pSelectPattern != 0);
-
- XalanNode* sourceNode = executionContext.getCurrentNode();
+ unsigned int nChildren = theNodeList.getLength();
- const XObjectPtr value(m_pSelectPattern->execute(sourceNode,
*this, executionContext));
- assert(value.null() == false);
-
- if(0 != executionContext.getTraceListeners())
+ for(unsigned int i = 0; i < nChildren; i++)
{
- executionContext.fireSelectEvent(
- SelectionEvent(
- executionContext,
- sourceNode,
- *this,
-
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
- *m_pSelectPattern,
- value));
+ assert(theNodeList.item(i) != 0);
+ cloneNode(executionContext, *theNodeList.item(i));
}
+}
- const XObject::eObjectType type = value->getType();
- switch(type)
- {
- case XObject::eTypeBoolean:
- case XObject::eTypeNumber:
- case XObject::eTypeString:
- executionContext.characters(value);
- break;
- case XObject::eTypeNodeSet:
- {
- const NodeRefListBase& nl = value->nodeset();
-
- unsigned int nChildren = nl.getLength();
+inline void
+ElemCopyOf::cloneNode(
+ StylesheetExecutionContext&
executionContext,
+ XalanNode&
theNode) const
+{
+ XalanNode* pos = &theNode;
- for(unsigned int i = 0; i < nChildren; i++)
+ while(pos != 0)
+ {
+ if(pos->getNodeType() != XalanNode::ATTRIBUTE_NODE)
{
- XalanNode* pos = nl.item(i);
- XalanNode* const top = pos;
-
- while(pos != 0)
- {
- if(pos->getNodeType() !=
XalanNode::ATTRIBUTE_NODE)
- {
- executionContext.flushPending();
- }
+ executionContext.flushPending();
+ }
- executionContext.cloneToResultTree(
+ executionContext.cloneToResultTree(
*pos,
false,
false,
true);
+
+ XalanNode* nextNode = pos->getFirstChild();
+
+ while(nextNode == 0)
+ {
+ if(XalanNode::ELEMENT_NODE == pos->getNodeType())
+ {
+
executionContext.endElement(c_wstr(pos->getNodeName()));
+ }
+
+ if(&theNode == pos)
+ break;
- XalanNode* nextNode = pos->getFirstChild();
+ nextNode = pos->getNextSibling();
- while(nextNode == 0)
+ if(nextNode == 0)
+ {
+ pos = pos->getParentNode();
+
+ if(&theNode == pos)
{
if(XalanNode::ELEMENT_NODE ==
pos->getNodeType())
{
executionContext.endElement(c_wstr(pos->getNodeName()));
}
- if(top == pos)
- break;
+ nextNode = 0;
+ break;
+ }
+ }
+ }
- nextNode = pos->getNextSibling();
+ pos = nextNode;
+ }
+}
- if(nextNode == 0)
- {
- pos = pos->getParentNode();
- if(top == pos)
- {
-
if(XalanNode::ELEMENT_NODE == pos->getNodeType())
- {
-
executionContext.endElement(c_wstr(pos->getNodeName()));
- }
-
- nextNode = 0;
- break;
- }
- }
- }
- pos = nextNode;
- }
+void
+ElemCopyOf::execute(StylesheetExecutionContext&
executionContext) const
+{
+ ElemTemplateElement::execute(executionContext);
+
+ assert(m_selectPattern != 0);
+
+ XalanNode* const sourceNode = executionContext.getCurrentNode();
+ assert(sourceNode != 0);
+
+ if (m_isDot == true)
+ {
+ if(0 != executionContext.getTraceListeners())
+ {
+ executionContext.fireSelectEvent(
+ SelectionEvent(
+ executionContext,
+ sourceNode,
+ *this,
+
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
+ *m_selectPattern,
+ XObjectPtr()));
}
- break;
+
+ cloneNode(executionContext, *sourceNode);
}
+ else
+ {
+ const XObjectPtr
value(m_selectPattern->execute(sourceNode, *this, executionContext));
+ assert(value.null() == false);
+
+ if(0 != executionContext.getTraceListeners())
+ {
+ executionContext.fireSelectEvent(
+ SelectionEvent(
+ executionContext,
+ sourceNode,
+ *this,
+
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
+ *m_selectPattern,
+ value));
+ }
- case XObject::eTypeResultTreeFrag:
- executionContext.outputResultTreeFragment(*value.get());
- break;
-
- default:
- executionContext.characters(value);
- break;
+ const XObject::eObjectType type = value->getType();
+
+ switch(type)
+ {
+ case XObject::eTypeBoolean:
+ case XObject::eTypeNumber:
+ case XObject::eTypeString:
+ executionContext.characters(value);
+ break;
+
+ case XObject::eTypeNodeSet:
+ cloneNodeSet(executionContext, value->nodeset());
+ break;
+
+ case XObject::eTypeResultTreeFrag:
+ executionContext.outputResultTreeFragment(*value.get());
+ break;
+
+ default:
+ executionContext.characters(value);
+ break;
+ }
}
}
1.10 +15 -2 xml-xalan/c/src/XSLT/ElemCopyOf.hpp
Index: ElemCopyOf.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemCopyOf.hpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ElemCopyOf.hpp 2001/03/09 16:20:04 1.9
+++ ElemCopyOf.hpp 2001/07/08 18:41:22 1.10
@@ -58,7 +58,7 @@
#define XALAN_ELEMCOPYOF_HEADER_GUARD
/**
- * $Id: ElemCopyOf.hpp,v 1.9 2001/03/09 16:20:04 auriemma Exp $
+ * $Id: ElemCopyOf.hpp,v 1.10 2001/07/08 18:41:22 dbertoni Exp $
*
*
* $State: Exp $
@@ -76,6 +76,7 @@
+class NodeRefListBase;
class XPath;
@@ -110,7 +111,19 @@
private:
- const XPath* m_pSelectPattern;
+ void
+ cloneNodeSet(
+ StylesheetExecutionContext&
executionContext,
+ const NodeRefListBase& theNodeList)
const;
+
+ void
+ cloneNode(
+ StylesheetExecutionContext&
executionContext,
+ XalanNode&
theNode) const;
+
+ const XPath* m_selectPattern;
+
+ bool m_isDot;
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]