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]

Reply via email to