dbertoni    2002/07/08 23:19:41

  Modified:    c/src/XSLT ElemAttribute.cpp ElemComment.cpp ElemCopyOf.cpp
                        ElemPI.cpp ExtensionNSHandler.cpp
                        StylesheetExecutionContext.hpp
                        StylesheetExecutionContextDefault.cpp
                        StylesheetExecutionContextDefault.hpp
                        XSLTEngineImpl.cpp XSLTEngineImpl.hpp
                        XSLTProcessor.hpp
  Log:
  Fixes for limiting content of certain instructions to text nodes.
  
  Revision  Changes    Path
  1.38      +2 -0      xml-xalan/c/src/XSLT/ElemAttribute.cpp
  
  Index: ElemAttribute.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemAttribute.cpp,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- ElemAttribute.cpp 6 May 2002 05:31:57 -0000       1.37
  +++ ElemAttribute.cpp 9 Jul 2002 06:19:40 -0000       1.38
  @@ -403,6 +403,8 @@
                // the result attribute.
                if (indexOfNSSep == origAttrNameLength || 
!isEmpty(attrNameSpace))
                {
  +                     
StylesheetExecutionContext::SetAndRestoreCopyTextNodesOnly      
theSetAndRestore(executionContext, true);
  +
                        childrenToResultAttribute(
                                executionContext,
                                attrName);
  
  
  
  1.15      +2 -0      xml-xalan/c/src/XSLT/ElemComment.cpp
  
  Index: ElemComment.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemComment.cpp,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- ElemComment.cpp   23 Feb 2002 04:23:16 -0000      1.14
  +++ ElemComment.cpp   9 Jul 2002 06:19:40 -0000       1.15
  @@ -122,6 +122,8 @@
   {
        ElemTemplateElement::execute(executionContext);
   
  +     StylesheetExecutionContext::SetAndRestoreCopyTextNodesOnly      
theSetAndRestore(executionContext, true);
  +
       childrenToResultComment(executionContext);
   }
   
  
  
  
  1.26      +5 -1      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.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- ElemCopyOf.cpp    23 Feb 2002 04:23:16 -0000      1.25
  +++ ElemCopyOf.cpp    9 Jul 2002 06:19:40 -0000       1.26
  @@ -143,6 +143,9 @@
                        StylesheetExecutionContext&             
executionContext,
                        XalanNode&                                              
theNode) const
   {
  +#if 1
  +     executionContext.cloneToResultTree(theNode, this);
  +#else
        XalanNode*                              pos = &theNode;
        XalanNode::NodeType             posNodeType = pos->getNodeType();
   
  @@ -202,6 +205,7 @@
                        posNodeType = pos->getNodeType();
                }
        }
  +#endif
   }
   
   
  @@ -281,7 +285,7 @@
                        break;
   
                case XObject::eTypeResultTreeFrag:
  -                     executionContext.outputResultTreeFragment(*value.get());
  +                     executionContext.outputResultTreeFragment(*value.get(), 
this);
                        break;
   
                default:
  
  
  
  1.21      +2 -0      xml-xalan/c/src/XSLT/ElemPI.cpp
  
  Index: ElemPI.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemPI.cpp,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- ElemPI.cpp        23 Feb 2002 04:23:16 -0000      1.20
  +++ ElemPI.cpp        9 Jul 2002 06:19:40 -0000       1.21
  @@ -155,6 +155,8 @@
                executionContext.error("processing-instruction name must be a 
valid NCName", 0, this);
        }
   
  +     StylesheetExecutionContext::SetAndRestoreCopyTextNodesOnly      
theSetAndRestore(executionContext, true);
  +
        childrenToResultPI(
                        executionContext,
                        piName);
  
  
  
  1.11      +1 -1      xml-xalan/c/src/XSLT/ExtensionNSHandler.cpp
  
  Index: ExtensionNSHandler.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ExtensionNSHandler.cpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ExtensionNSHandler.cpp    13 Aug 2001 17:08:53 -0000      1.10
  +++ ExtensionNSHandler.cpp    9 Jul 2002 06:19:40 -0000       1.11
  @@ -248,7 +248,7 @@
   
        if (result.null() == false) 
        {
  -             executionContext.outputToResultTree(*result);
  +             executionContext.outputToResultTree(*result, 0);
        }
   }
   
  
  
  
  1.74      +82 -10    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.73
  retrieving revision 1.74
  diff -u -r1.73 -r1.74
  --- StylesheetExecutionContext.hpp    29 May 2002 18:21:52 -0000      1.73
  +++ StylesheetExecutionContext.hpp    9 Jul 2002 06:19:40 -0000       1.74
  @@ -172,6 +172,61 @@
        getQuietConflictWarnings() const = 0;
   
        /**
  +      * If this function returns true, only text nodes can
  +      * be copied to the result tree.
  +      * 
  +      * @return true or false
  +      */
  +     virtual bool
  +     getCopyTextNodesOnly() const = 0;
  +
  +     /**
  +      * Set the flag that determines if only text nodes
  +      * can be copied to the result tree.
  +      * 
  +      * @param fValue The value of the flag
  +      */
  +     virtual void
  +     setCopyTextNodesOnly(bool       fValue) = 0;
  +
  +     /*
  +      * A class to manage setting and restoring the flag
  +      * for restricting copying only text nodes to the
  +      * result tree
  +      */
  +     class SetAndRestoreCopyTextNodesOnly
  +     {
  +     public:
  +
  +             SetAndRestoreCopyTextNodesOnly(
  +                     StylesheetExecutionContext&             
executionContext,
  +                     bool                                                    
fValue) :
  +                     m_executionContext(executionContext),
  +                     m_fValue(executionContext.getCopyTextNodesOnly())
  +             {
  +                     executionContext.setCopyTextNodesOnly(fValue);
  +             }
  +
  +             ~SetAndRestoreCopyTextNodesOnly()
  +             {
  +                     m_executionContext.setCopyTextNodesOnly(m_fValue);
  +             }
  +
  +     private:
  +
  +             // Not implemented...
  +             SetAndRestoreCopyTextNodesOnly(const 
SetAndRestoreCopyTextNodesOnly&);
  +
  +             SetAndRestoreCopyTextNodesOnly&
  +             operator=(const SetAndRestoreCopyTextNodesOnly&);
  +
  +             // Data members...
  +             StylesheetExecutionContext&             m_executionContext;
  +
  +             const bool                                              
m_fValue;
  +     };
  +
  +     /**
         * Retrieve root document for stylesheet.  Note that
         * this does not have to be a XalanDocument -- it can
         * be any node in a document.
  @@ -472,11 +527,11 @@
         * @param resolver    resolver for namespace resolution
         * @return pointer to resulting XObject
         */
  -     virtual const XObjectPtr
  -     executeXPath(
  -                     const XalanDOMString&   str,
  -                     XalanNode*                              contextNode,
  -                     const XalanElement&             resolver) = 0;
  +//   virtual const XObjectPtr
  +//   executeXPath(
  +//                   const XalanDOMString&   str,
  +//                   XalanNode*                              contextNode,
  +//                   const XalanElement&             resolver) = 0;
   
        /**
         * Create and initialize an xpath and return it. This is to be used to
  @@ -1006,7 +1061,18 @@
        flushPending() = 0;
   
        /**
  -      * Clone an element with or without children.
  +      * Clone a node to the result tree
  +      *
  +      * @param node      node to clone
  +      * @param styleNode     the stylesheet element that generated the clone.
  +      */
  +     virtual void
  +     cloneToResultTree(
  +                     const XalanNode&                        node,
  +                     const ElemTemplateElement*      styleNode) = 0;
  +
  +     /**
  +      * Clone a node to the result tree
         *
         * @param node                  node to clone
         * @param nodeType                              the type of the node
  @@ -1017,12 +1083,12 @@
         */
        virtual void
        cloneToResultTree(
  -                     XalanNode&                                      node,
  +                     const XalanNode&                        node,
                        XalanNode::NodeType                     nodeType,
                        bool                                            
isLiteral,
                        bool                                            
overrideStrip,
                        bool                                            
shouldCloneAttributes,
  -                     const ElemTemplateElement*      styleNode = 0) = 0;
  +                     const ElemTemplateElement*      styleNode) = 0;
   
        /**
         * Create an XObject that represents a Result tree fragment.
  @@ -1041,18 +1107,24 @@
         * This is public for access by extensions.
         *
         * @param obj the XObject to output
  +      * @param styleNode     the stylesheet element that generate the 
fragment.
         */
        virtual void
  -     outputToResultTree(const XObject&       xobj) = 0;
  +     outputToResultTree(
  +                     const XObject&                          xobj,
  +                     const ElemTemplateElement*      styleNode) = 0;
   
        /**
         * Given a result tree fragment, walk the tree and
         * output it to the result stream.
         *
         * @param theTree result tree fragment
  +      * @param styleNode     the stylesheet element that generate the 
fragment.
         */
        virtual void
  -     outputResultTreeFragment(const XObject&         theTree) = 0;
  +     outputResultTreeFragment(
  +                     const XObject&                          theTree,
  +                     const ElemTemplateElement*      styleNode) = 0;
   
        /**
         * Determine the full XSLT Namespace URI.
  
  
  
  1.92      +135 -7    
xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.cpp
  
  Index: StylesheetExecutionContextDefault.cpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.cpp,v
  retrieving revision 1.91
  retrieving revision 1.92
  diff -u -r1.91 -r1.92
  --- StylesheetExecutionContextDefault.cpp     29 May 2002 18:21:52 -0000      
1.91
  +++ StylesheetExecutionContextDefault.cpp     9 Jul 2002 06:19:40 -0000       
1.92
  @@ -167,7 +167,8 @@
        m_resultTreeFragAllocator(eResultTreeFragAllocatorBlockSize),
        m_documentFragmentAllocator(eDocumentFragmentAllocatorBlockSize),
        m_documentAllocator(eDocumentAllocatorBlockSize),
  -     m_usePerInstanceDocumentFactory(true)
  +     m_usePerInstanceDocumentFactory(true),
  +     m_cloneTextNodesOnly(false)
   {
   }
   
  @@ -207,7 +208,8 @@
        m_resultTreeFragAllocator(eResultTreeFragAllocatorBlockSize),
        m_documentFragmentAllocator(eDocumentFragmentAllocatorBlockSize),
        m_documentAllocator(eDocumentAllocatorBlockSize),
  -     m_usePerInstanceDocumentFactory(true)
  +     m_usePerInstanceDocumentFactory(true),
  +     m_cloneTextNodesOnly(false)
   {
   }
   
  @@ -230,6 +232,22 @@
   
   
   
  +bool
  +StylesheetExecutionContextDefault::getCopyTextNodesOnly() const
  +{
  +     return m_cloneTextNodesOnly;
  +}
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::setCopyTextNodesOnly(bool fValue)
  +{
  +     m_cloneTextNodesOnly = fValue;
  +}
  +
  +
  +
   XalanNode*
   StylesheetExecutionContextDefault::getRootDocument() const
   {
  @@ -939,7 +957,110 @@
   
   void
   StylesheetExecutionContextDefault::cloneToResultTree(
  -                     XalanNode&                                      node,
  +                     const XalanNode&                        node,
  +                     const ElemTemplateElement*      styleNode)
  +{
  +#if 1
  +     m_xsltProcessor->cloneToResultTree(node, m_cloneTextNodesOnly, 
styleNode);
  +#else
  +     XalanNode::NodeType             posNodeType = node.getNodeType();
  +
  +     if (this->m_cloneTextNodesOnly == true &&
  +             posNodeType != XalanNode::TEXT_NODE)
  +     {
  +             const Locator*          theLocator = 0;
  +             const char* const       theErrorMessage =
  +                                     "Only text nodes can be copied in this 
context.  The node is ignored";
  +
  +             if (styleNode != 0)
  +             {
  +                     theLocator = styleNode->getLocator();
  +             }
  +
  +             if (theLocator != 0)
  +             {
  +                     warn(
  +                             theErrorMessage,
  +                             &node,
  +                             theLocator);
  +             }
  +             else
  +             {
  +                     warn(
  +                             XalanDOMString(theErrorMessage),
  +                             &node,
  +                             styleNode);
  +             }
  +     }
  +     else
  +     {
  +             const XalanNode*        pos = &node;
  +
  +             while(pos != 0)
  +             {
  +                     if(posNodeType != XalanNode::ATTRIBUTE_NODE)
  +                     {
  +                             flushPending();
  +                     }
  +
  +                     cloneToResultTree(
  +                                                     *pos,
  +                                                     posNodeType,
  +                                                     false,
  +                                                     false,
  +                                                     true,
  +                                                     styleNode);
  +
  +                     const XalanNode*        nextNode = pos->getFirstChild();
  +
  +                     while(nextNode == 0)
  +                     {
  +                             if(XalanNode::ELEMENT_NODE == posNodeType)
  +                             {
  +                                     endElement(c_wstr(pos->getNodeName()));
  +                             }
  +
  +                             if(&node == pos)
  +                                     break;
  +
  +                             nextNode = pos->getNextSibling();
  +
  +                             if(nextNode == 0)
  +                             {
  +                                     pos = pos->getParentNode();
  +                                     assert(pos != 0);
  +
  +                                     posNodeType = pos->getNodeType();
  +
  +                                     if(&node == pos)
  +                                     {
  +                                             if(XalanNode::ELEMENT_NODE == 
posNodeType)
  +                                             {
  +                                                     
endElement(c_wstr(pos->getNodeName()));
  +                                             }
  +
  +                                             nextNode = 0;
  +                                             break;
  +                                     }
  +                             }
  +                     }
  +
  +                     pos = nextNode;
  +
  +                     if (pos != 0)
  +                     {
  +                             posNodeType = pos->getNodeType();
  +                     }
  +             }
  +     }
  +#endif
  +}
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::cloneToResultTree(
  +                     const XalanNode&                        node,
                        XalanNode::NodeType                     nodeType,
                        bool                                            
isLiteral,
                        bool                                            
overrideStrip,
  @@ -954,6 +1075,7 @@
                        isLiteral,
                        overrideStrip,
                        shouldCloneAttributes,
  +                     m_cloneTextNodesOnly,
                        styleNode);
   }
   
  @@ -1019,21 +1141,25 @@
   
   
   void
  -StylesheetExecutionContextDefault::outputToResultTree(const XObject& xobj)
  +StylesheetExecutionContextDefault::outputToResultTree(
  +                     const XObject&                          xobj,
  +                     const ElemTemplateElement*      styleNode)
   {
        assert(m_xsltProcessor != 0);
   
  -     m_xsltProcessor->outputToResultTree(xobj);
  +     m_xsltProcessor->outputToResultTree(xobj, m_cloneTextNodesOnly, 
styleNode);
   }
   
   
   
   void
  -StylesheetExecutionContextDefault::outputResultTreeFragment(const XObject&   
theTree)
  +StylesheetExecutionContextDefault::outputResultTreeFragment(
  +                     const XObject&                          theTree,
  +                     const ElemTemplateElement*      styleNode)
   {
        assert(m_xsltProcessor != 0);
   
  -     m_xsltProcessor->outputResultTreeFragment(theTree);
  +     m_xsltProcessor->outputResultTreeFragment(theTree, 
m_cloneTextNodesOnly, styleNode);
   }
   
   
  @@ -1585,6 +1711,8 @@
   
        // Reset the default execution context...
        m_xpathExecutionContextDefault.reset();
  +
  +     m_cloneTextNodesOnly = false;
   }
   
   
  
  
  
  1.79      +22 -4     
xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.hpp
  
  Index: StylesheetExecutionContextDefault.hpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.hpp,v
  retrieving revision 1.78
  retrieving revision 1.79
  diff -u -r1.78 -r1.79
  --- StylesheetExecutionContextDefault.hpp     29 May 2002 18:21:52 -0000      
1.78
  +++ StylesheetExecutionContextDefault.hpp     9 Jul 2002 06:19:40 -0000       
1.79
  @@ -283,6 +283,12 @@
        virtual bool
        getQuietConflictWarnings() const;
   
  +     virtual bool
  +     getCopyTextNodesOnly() const;
  +
  +     virtual void
  +     setCopyTextNodesOnly(bool       fValue);
  +
        virtual XalanNode*
        getRootDocument() const;
   
  @@ -510,12 +516,17 @@
   
        virtual void
        cloneToResultTree(
  -                     XalanNode&                                      node,
  +                     const XalanNode&                        node,
  +                     const ElemTemplateElement*      styleNode);
  +
  +     virtual void
  +     cloneToResultTree(
  +                     const XalanNode&                        node,
                        XalanNode::NodeType                     nodeType,
                        bool                                            
isLiteral,
                        bool                                            
overrideStrip,
                        bool                                            
shouldCloneAttributes,
  -                     const ElemTemplateElement*      styleNode = 0);
  +                     const ElemTemplateElement*      styleNode);
   
        virtual const XObjectPtr
        createXResultTreeFrag(
  @@ -523,10 +534,14 @@
                        XalanNode*                                      
sourceNode);
   
        virtual void
  -     outputToResultTree(const XObject&       xobj);
  +     outputToResultTree(
  +                     const XObject&                          xobj,
  +                     const ElemTemplateElement*      styleNode);
   
        virtual void
  -     outputResultTreeFragment(const XObject&         theTree);
  +     outputResultTreeFragment(
  +                     const XObject&                          theTree,
  +                     const ElemTemplateElement*      styleNode);
   
        virtual const XalanDOMString&
        getXSLNameSpaceURL() const;
  @@ -1132,6 +1147,9 @@
        // If true, we will use a separate document factory for
        // result tree fragments.
        bool                                                            
m_usePerInstanceDocumentFactory;
  +
  +     // If true, only text nodes will be cloned in the output...
  +     bool                                                            
m_cloneTextNodesOnly;
   
        static XalanNumberFormatFactory         
s_defaultXalanNumberFormatFactory;
   
  
  
  
  1.146     +443 -220  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.145
  retrieving revision 1.146
  diff -u -r1.145 -r1.146
  --- XSLTEngineImpl.cpp        26 Jun 2002 01:20:25 -0000      1.145
  +++ XSLTEngineImpl.cpp        9 Jul 2002 06:19:40 -0000       1.146
  @@ -970,103 +970,6 @@
   
   
   
  -void
  -XSLTEngineImpl::outputToResultTree(const XObject&    value)
  -{
  -     const XObject::eObjectType      type = value.getType();
  -
  -     switch(type)
  -     {
  -     case XObject::eTypeBoolean:
  -     case XObject::eTypeNumber:
  -     case XObject::eTypeString:
  -             {
  -                     const XalanDOMString&   s = value.str();
  -
  -                     characters(toCharArray(s), 0, length(s));
  -             }
  -             break;                          
  -
  -     case XObject::eTypeNodeSet:
  -             {
  -                     const NodeRefListBase&  nl = value.nodeset();
  -
  -                     const NodeRefListBase::size_type        nChildren = 
nl.getLength();
  -
  -                     for(NodeRefListBase::size_type i = 0; i < nChildren; 
i++)
  -                     {
  -                             XalanNode*                      pos = 
nl.item(i);
  -                             assert(pos != 0);
  -
  -                             XalanNode* const        top = pos;
  -
  -                             while(0 != pos)
  -                             {
  -                                     flushPending();
  -
  -                                     XalanNode::NodeType             
posNodeType = pos->getNodeType();
  -
  -                                     cloneToResultTree(*pos, posNodeType, 
false, false, true);
  -
  -                                     XalanNode*      nextNode = 
pos->getFirstChild();
  -
  -                                     while(0 == nextNode)
  -                                     {
  -                                             if(XalanNode::ELEMENT_NODE == 
posNodeType)
  -                                             {
  -                                                     
endElement(c_wstr(pos->getNodeName()));
  -                                             }
  -
  -                                             if(top == pos)
  -                                                     break;
  -
  -                                             nextNode = 
pos->getNextSibling();
  -
  -                                             if(0 == nextNode)
  -                                             {
  -                                                     pos = 
pos->getParentNode();
  -                                                     assert(pos != 0);
  -
  -                                                     posNodeType = 
pos->getNodeType();
  -
  -                                                     if(top == pos)
  -                                                     {
  -                                                             
if(XalanNode::ELEMENT_NODE == posNodeType)
  -                                                             {
  -                                                                     
endElement(c_wstr(pos->getNodeName()));
  -                                                             }
  -
  -                                                             nextNode = 0;
  -                                                             break;
  -                                                     }
  -                                             }
  -                                     }
  -
  -                                     pos = nextNode;
  -
  -                                     if (pos != 0)
  -                                     {
  -                                             posNodeType = 
pos->getNodeType();
  -                                     }
  -                             }
  -                     }
  -             }
  -             break;
  -             
  -     case XObject::eTypeResultTreeFrag:
  -             outputResultTreeFragment(value);
  -             break;
  -
  -     case XObject::eTypeNull:
  -     case XObject::eTypeUnknown:
  -     case XObject::eUnknown:
  -     default:
  -             assert(0);
  -     }
  -}
  -
  -
  -
   const StylesheetRoot*
   XSLTEngineImpl::getStylesheetRoot() const
   {
  @@ -2287,102 +2190,166 @@
   
   void
   XSLTEngineImpl::cloneToResultTree(
  -                     XalanNode&                                      node,
  -                     XalanNode::NodeType                     nodeType,
  -                     bool                                            
isLiteral,
  -                     bool                                            
overrideStrip,
  -                     bool                                            
shouldCloneAttributes,
  +                     const XalanText&        node,
  +                     bool                            isLiteral,
  +                     bool                            overrideStrip)
  +{
  +     bool    stripWhiteSpace = false;
  +
  +     // If stripWhiteSpace is false, then take this as an override and 
  +     // just preserve the space, otherwise use the XSL whitespace rules.
  +     if(!overrideStrip)
  +     {
  +             stripWhiteSpace = isLiteral ? true : false;
  +             // stripWhiteSpace = isLiteral ? true : 
shouldStripSourceNode(*m_executionContext, node);
  +     }
  +
  +     const bool      isIgnorableWhitespace = node.isIgnorableWhitespace();
  +
  +     if(stripWhiteSpace == false || isIgnorableWhitespace == false)
  +     {
  +             assert(node.getParentNode() == 0 ||
  +                        node.getParentNode()->getNodeType() != 
XalanNode::DOCUMENT_NODE);
  +
  +             const XalanDOMString&   data = node.getData();
  +
  +             if(0 != length(data))
  +             {
  +                     if(isIgnorableWhitespace == true)
  +                     {
  +                             ignorableWhitespace(toCharArray(data), 
length(data));
  +                     }
  +                     else
  +                     {
  +                             characters(toCharArray(data), 0, length(data));
  +                     }
  +             }
  +     }                       
  +}
  +
  +
  +
  +void
  +XSLTEngineImpl::cloneToResultTree(
  +                     const XalanNode&                        node,
  +                     bool                                            
cloneTextNodesOnly,
                        const ElemTemplateElement*      styleNode)
   {
  -     assert(nodeType == node.getNodeType());
  -     assert(m_executionContext != 0);
  +     XalanNode::NodeType             posNodeType = node.getNodeType();
   
  -     switch(nodeType)
  +     if (cloneTextNodesOnly == true &&
  +             posNodeType != XalanNode::TEXT_NODE)
        {
  -     case XalanNode::TEXT_NODE:
  +             const Locator*          theLocator = 0;
  +             const char* const       theErrorMessage =
  +                                     "Only text nodes can be copied in this 
context.  The node is ignored";
  +
  +             if (styleNode != 0)
  +             {
  +                     theLocator = styleNode->getLocator();
  +             }
  +
  +             if (theLocator != 0)
  +             {
  +                     warn(
  +                             XalanDOMString(theErrorMessage),
  +                             *theLocator,
  +                             &node);
  +             }
  +             else
                {
  -                     bool    stripWhiteSpace = false;
  +                     warn(
  +                             XalanDOMString(theErrorMessage),
  +                             &node,
  +                             styleNode);
  +             }
  +     }
  +     else
  +     {
  +             const XalanNode*        pos = &node;
   
  -                     // If stripWhiteSpace is false, then take this as an 
override and 
  -                     // just preserve the space, otherwise use the XSL 
whitespace rules.
  -                     if(!overrideStrip)
  +             while(pos != 0)
  +             {
  +                     if(posNodeType != XalanNode::ATTRIBUTE_NODE)
                        {
  -                             stripWhiteSpace = isLiteral ? true : false;
  -                             // stripWhiteSpace = isLiteral ? true : 
shouldStripSourceNode(*m_executionContext, node);
  +                             flushPending();
                        }
   
  -                     const XalanText&        tx =
  -#if defined(XALAN_OLD_STYLE_CASTS)
  -                             (const XalanText&)node;
  -#else
  -                             static_cast<const XalanText&>(node);
  -#endif
  +                     cloneToResultTree(
  +                                                     *pos,
  +                                                     posNodeType,
  +                                                     false,
  +                                                     false,
  +                                                     true,
  +                                                     false,
  +                                                     styleNode);
   
  -                     const bool      isIgnorableWhitespace = 
tx.isIgnorableWhitespace();
  +                     const XalanNode*        nextNode = pos->getFirstChild();
   
  -                     if(stripWhiteSpace == false || isIgnorableWhitespace == 
false)
  +                     while(nextNode == 0)
                        {
  -                             assert(tx.getParentNode() == 0 ||
  -                                        tx.getParentNode()->getNodeType() != 
XalanNode::DOCUMENT_NODE);
  +                             if(XalanNode::ELEMENT_NODE == posNodeType)
  +                             {
  +                                     endElement(c_wstr(pos->getNodeName()));
  +                             }
   
  -                             const XalanDOMString&   data = tx.getData();
  +                             if(&node == pos)
  +                                     break;
   
  -                             if(0 != length(data))
  +                             nextNode = pos->getNextSibling();
  +
  +                             if(nextNode == 0)
                                {
  -                                     if(isIgnorableWhitespace == true)
  -                                     {
  -                                             
ignorableWhitespace(toCharArray(data), length(data));
  -                                     }
  -                                     else
  +                                     pos = pos->getParentNode();
  +                                     assert(pos != 0);
  +
  +                                     posNodeType = pos->getNodeType();
  +
  +                                     if(&node == pos)
                                        {
  -                                             characters(toCharArray(data), 
0, length(data));
  +                                             if(XalanNode::ELEMENT_NODE == 
posNodeType)
  +                                             {
  +                                                     
endElement(c_wstr(pos->getNodeName()));
  +                                             }
  +
  +                                             nextNode = 0;
  +                                             break;
                                        }
                                }
  -                     }                       
  -             }
  -             break;
  -
  -     case XalanNode::ELEMENT_NODE:
  -             {
  -                     const XalanDOMString&   theElementName =
  -                             node.getNodeName();
  +                     }
   
  -                     startElement(c_wstr(theElementName));
  +                     pos = nextNode;
   
  -                     if(shouldCloneAttributes == true)
  +                     if (pos != 0)
                        {
  -                             copyAttributesToAttList(
  -                                     node,
  -                                     getPendingAttributesImpl());
  -
  -                             copyNamespaceAttributes(node);
  +                             posNodeType = pos->getNodeType();
                        }
  -
  -                     checkDefaultNamespace(theElementName, 
node.getNamespaceURI());
                }
  -             break;
  +     }
  +}
   
  -     case XalanNode::CDATA_SECTION_NODE:
  -             {
  -                     const XalanDOMString&   data = node.getNodeValue();
   
  -                     cdata(toCharArray(data), 0, length(data));
  -             }
  -             break;
   
  -     case XalanNode::ATTRIBUTE_NODE:
  -             if (length(getPendingElementName()) != 0)
  -             {
  -                     addResultAttribute(
  -                                     getPendingAttributesImpl(),
  -                                     node.getNodeName(),
  -                                     node.getNodeValue());
  -             }
  -             else
  +void
  +XSLTEngineImpl::cloneToResultTree(
  +                     const XalanNode&                        node,
  +                     XalanNode::NodeType                     nodeType,
  +                     bool                                            
isLiteral,
  +                     bool                                            
overrideStrip,
  +                     bool                                            
shouldCloneAttributes,
  +                     bool                                            
cloneTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode)
  +{
  +     assert(nodeType == node.getNodeType());
  +     assert(m_executionContext != 0);
  +
  +     if(cloneTextNodesOnly == true)
  +     {
  +             if (nodeType != XalanNode::TEXT_NODE)
                {
                        const Locator*          theLocator = 0;
                        const char* const       theErrorMessage =
  -                             "Attempting to add an attribute when there is 
no open element.  The attribute will be ignored";
  +                                     "Only text nodes can be copied in this 
context.  The node is ignored";
   
                        if (styleNode != 0)
                        {
  @@ -2404,43 +2371,269 @@
                                        styleNode);
                        }
                }
  -             break;
  +             else
  +             {
  +                     const XalanText&        tx =
  +#if defined(XALAN_OLD_STYLE_CASTS)
  +                             (const XalanText&)node;
  +#else
  +                             static_cast<const XalanText&>(node);
  +#endif
   
  -     case XalanNode::COMMENT_NODE:
  -             comment(c_wstr(node.getNodeValue()));
  -             break;
  +                     cloneToResultTree(tx, isLiteral, overrideStrip);
  +             }
  +     }
  +     else
  +     {
  +             switch(nodeType)
  +             {
  +             case XalanNode::TEXT_NODE:
  +                     {
  +                             const XalanText&        tx =
  +     #if defined(XALAN_OLD_STYLE_CASTS)
  +                                     (const XalanText&)node;
  +     #else
  +                                     static_cast<const XalanText&>(node);
  +     #endif
  +
  +                             cloneToResultTree(tx, isLiteral, overrideStrip);
  +                     }
  +                     break;
  +
  +             case XalanNode::ELEMENT_NODE:
  +                     {
  +                             const XalanDOMString&   theElementName =
  +                                     node.getNodeName();
  +
  +                             startElement(c_wstr(theElementName));
  +
  +                             if(shouldCloneAttributes == true)
  +                             {
  +                                     copyAttributesToAttList(
  +                                             node,
  +                                             getPendingAttributesImpl());
  +
  +                                     copyNamespaceAttributes(node);
  +                             }
  +
  +                             checkDefaultNamespace(theElementName, 
node.getNamespaceURI());
  +                     }
  +                     break;
  +
  +             case XalanNode::CDATA_SECTION_NODE:
  +                     {
  +                             const XalanDOMString&   data = 
node.getNodeValue();
  +
  +                             cdata(toCharArray(data), 0, length(data));
  +                     }
  +                     break;
  +
  +             case XalanNode::ATTRIBUTE_NODE:
  +                     if (length(getPendingElementName()) != 0)
  +                     {
  +                             addResultAttribute(
  +                                             getPendingAttributesImpl(),
  +                                             node.getNodeName(),
  +                                             node.getNodeValue());
  +                     }
  +                     else
  +                     {
  +                             const Locator*          theLocator = 0;
  +                             const char* const       theErrorMessage =
  +                                     "Attempting to add an attribute when 
there is no open element.  The attribute will be ignored";
   
  -     case XalanNode::DOCUMENT_FRAGMENT_NODE:
  -             error("No clone of a document fragment!");
  +                             if (styleNode != 0)
  +                             {
  +                                     theLocator = styleNode->getLocator();
  +                             }
  +
  +                             if (theLocator != 0)
  +                             {
  +                                     warn(
  +                                             XalanDOMString(theErrorMessage),
  +                                             *theLocator,
  +                                             &node);
  +                             }
  +                             else
  +                             {
  +                                     warn(
  +                                             XalanDOMString(theErrorMessage),
  +                                             &node,
  +                                             styleNode);
  +                             }
  +                     }
  +                     break;
  +
  +             case XalanNode::COMMENT_NODE:
  +                     comment(c_wstr(node.getNodeValue()));
  +                     break;
  +
  +             case XalanNode::DOCUMENT_FRAGMENT_NODE:
  +                     error("No clone of a document fragment!");
  +                     break;
  +             
  +             case XalanNode::ENTITY_REFERENCE_NODE:
  +                     entityReference(c_wstr(node.getNodeName()));
  +                     break;
  +
  +             case XalanNode::PROCESSING_INSTRUCTION_NODE:
  +                     processingInstruction(
  +                                     c_wstr(node.getNodeName()),
  +                                     c_wstr(node.getNodeValue()));
  +                     break;
  +
  +             // Can't really do this, but we won't throw an error so that 
copy-of will
  +             // work
  +             case XalanNode::DOCUMENT_NODE:
  +             case XalanNode::DOCUMENT_TYPE_NODE:
                break;
  -     
  -     case XalanNode::ENTITY_REFERENCE_NODE:
  -             entityReference(c_wstr(node.getNodeName()));
  +
  +             default:
  +                     error("Cannot create item in result tree: " + 
node.getNodeName());
                break;
  +             }
  +     }
  +}
  +
  +
  +
  +void
  +XSLTEngineImpl::outputToResultTree(
  +                     const XObject&                          value,
  +                     bool                                            
outputTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode)
  +{
  +     const XObject::eObjectType      type = value.getType();
   
  -     case XalanNode::PROCESSING_INSTRUCTION_NODE:
  -             processingInstruction(
  -                             c_wstr(node.getNodeName()),
  -                             c_wstr(node.getNodeValue()));
  +     switch(type)
  +     {
  +     case XObject::eTypeBoolean:
  +     case XObject::eTypeNumber:
  +     case XObject::eTypeString:
  +             {
  +                     const XalanDOMString&   s = value.str();
  +
  +                     characters(toCharArray(s), 0, length(s));
  +             }
                break;
   
  -     // Can't really do this, but we won't throw an error so that copy-of 
will
  -     // work
  -     case XalanNode::DOCUMENT_NODE:
  -     case XalanNode::DOCUMENT_TYPE_NODE:
  -     break;
  +     case XObject::eTypeNodeSet:
  +             {
  +                     const NodeRefListBase&  nl = value.nodeset();
  +
  +                     const NodeRefListBase::size_type        nChildren = 
nl.getLength();
   
  -     default:
  -             error("Cannot create item in result tree: " + 
node.getNodeName());
  -     break;
  +                     for(NodeRefListBase::size_type i = 0; i < nChildren; 
i++)
  +                     {
  +                             XalanNode*                      pos = 
nl.item(i);
  +                             assert(pos != 0);
  +
  +                             XalanNode::NodeType             posNodeType = 
pos->getNodeType();
  +
  +                             if (outputTextNodesOnly == true &&
  +                                     posNodeType != XalanNode::TEXT_NODE)
  +                             {
  +                                     const Locator*          theLocator = 0;
  +                                     const char* const       theErrorMessage 
=
  +                                                     "Only text nodes can be 
copied in this context.  The node is ignored";
  +
  +                                     if (styleNode != 0)
  +                                     {
  +                                             theLocator = 
styleNode->getLocator();
  +                                     }
  +
  +                                     if (theLocator != 0)
  +                                     {
  +                                             warn(
  +                                                     
XalanDOMString(theErrorMessage),
  +                                                     *theLocator,
  +                                                     pos);
  +                                     }
  +                                     else
  +                                     {
  +                                             warn(
  +                                                     
XalanDOMString(theErrorMessage),
  +                                                     pos,
  +                                                     styleNode);
  +                                     }
  +                             }
  +                             else
  +                             {
  +                                     XalanNode* const        top = pos;
  +
  +                                     while(0 != pos)
  +                                     {
  +                                             flushPending();
  +
  +                                             XalanNode::NodeType             
posNodeType = pos->getNodeType();
  +
  +                                             cloneToResultTree(*pos, 
posNodeType, false, false, false, false, styleNode);
  +
  +                                             XalanNode*      nextNode = 
pos->getFirstChild();
  +
  +                                             while(0 == nextNode)
  +                                             {
  +                                                     
if(XalanNode::ELEMENT_NODE == posNodeType)
  +                                                     {
  +                                                             
endElement(c_wstr(pos->getNodeName()));
  +                                                     }
  +
  +                                                     if(top == pos)
  +                                                             break;
  +
  +                                                     nextNode = 
pos->getNextSibling();
  +
  +                                                     if(0 == nextNode)
  +                                                     {
  +                                                             pos = 
pos->getParentNode();
  +                                                             assert(pos != 
0);
  +
  +                                                             posNodeType = 
pos->getNodeType();
  +
  +                                                             if(top == pos)
  +                                                             {
  +                                                                     
if(XalanNode::ELEMENT_NODE == posNodeType)
  +                                                                     {
  +                                                                             
endElement(c_wstr(pos->getNodeName()));
  +                                                                     }
  +
  +                                                                     
nextNode = 0;
  +                                                                     break;
  +                                                             }
  +                                                     }
  +                                             }
   
  +                                             pos = nextNode;
  +
  +                                             if (pos != 0)
  +                                             {
  +                                                     posNodeType = 
pos->getNodeType();
  +                                             }
  +                                     }
  +                             }
  +                     }
  +             }
  +             break;
  +             
  +     case XObject::eTypeResultTreeFrag:
  +             outputResultTreeFragment(value, outputTextNodesOnly, styleNode);
  +             break;
  +
  +     case XObject::eTypeNull:
  +     case XObject::eTypeUnknown:
  +     case XObject::eUnknown:
  +     default:
  +             assert(0);
        }
   }
   
   
   
   void
  -XSLTEngineImpl::outputResultTreeFragment(const XObject&              theTree)
  +XSLTEngineImpl::outputResultTreeFragment(
  +                     const XObject&                          theTree,
  +                     bool                                            
outputTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode)
   {
        const ResultTreeFragBase&       docFrag = theTree.rtree();
   
  @@ -2456,64 +2649,94 @@
   
                XalanNode::NodeType             posNodeType = 
pos->getNodeType();
   
  -             XalanNode* const                top = pos;
  -
  -             while(0 != pos)
  +             if (outputTextNodesOnly == true &&
  +                     posNodeType != XalanNode::TEXT_NODE)
                {
  -                     flushPending();
  +                     const Locator*          theLocator = 0;
  +                     const char* const       theErrorMessage =
  +                                     "Only text nodes can be copied in this 
context.  The node is ignored";
   
  -                     cloneToResultTree(*pos, posNodeType, false, false, 
true);
  +                     if (styleNode != 0)
  +                     {
  +                             theLocator = styleNode->getLocator();
  +                     }
   
  -                     XalanNode*      nextNode = pos->getFirstChild();
  +                     if (theLocator != 0)
  +                     {
  +                             warn(
  +                                     XalanDOMString(theErrorMessage),
  +                                     *theLocator,
  +                                     pos);
  +                     }
  +                     else
  +                     {
  +                             warn(
  +                                     XalanDOMString(theErrorMessage),
  +                                     pos,
  +                                     styleNode);
  +                     }
  +             }
  +             else
  +             {
  +                     XalanNode* const                top = pos;
   
  -                     while(0 == nextNode)
  +                     while(0 != pos)
                        {
  -                             if(XalanNode::ELEMENT_NODE == posNodeType)
  -                             {
  -                                     endElement(c_wstr(pos->getNodeName()));
  -                             }
  +                             flushPending();
   
  -                             if(top == pos)
  -                                     break;
  +                             cloneToResultTree(*pos, posNodeType, false, 
false, true, false, styleNode);
   
  -                             nextNode = pos->getNextSibling();
  +                             XalanNode*      nextNode = pos->getFirstChild();
   
  -                             if(0 == nextNode)
  +                             while(0 == nextNode)
                                {
  -                                     pos = pos->getParentNode();
  -
  -                                     if(0 == pos)
  +                                     if(XalanNode::ELEMENT_NODE == 
posNodeType)
                                        {
  -                                             nextNode = 0;
  +                                             
endElement(c_wstr(pos->getNodeName()));
  +                                     }
   
  +                                     if(top == pos)
                                                break;
  -                                     }
  -                                     else
  +
  +                                     nextNode = pos->getNextSibling();
  +
  +                                     if(0 == nextNode)
                                        {
  -                                             assert(0 != pos);
  +                                             pos = pos->getParentNode();
   
  -                                             posNodeType = 
pos->getNodeType();
  +                                             if(0 == pos)
  +                                             {
  +                                                     nextNode = 0;
   
  -                                             if(top == pos)
  +                                                     break;
  +                                             }
  +                                             else
                                                {
  -                                                     
if(XalanNode::ELEMENT_NODE == posNodeType)
  +                                                     assert(0 != pos);
  +
  +                                                     posNodeType = 
pos->getNodeType();
  +
  +                                                     if(top == pos)
                                                        {
  -                                                             
endElement(c_wstr(pos->getNodeName()));
  -                                                     }
  +                                                             
if(XalanNode::ELEMENT_NODE == posNodeType)
  +                                                             {
  +                                                                     
endElement(c_wstr(pos->getNodeName()));
  +                                                             }
   
  -                                                     nextNode = 0;
  +                                                             nextNode = 0;
   
  -                                                     break;
  +                                                             break;
  +                                                     }
                                                }
                                        }
                                }
  -                     }
   
  -                     pos = nextNode;
  +                             pos = nextNode;
   
  -                     if (pos != 0)
  -                     {
  -                             posNodeType = pos->getNodeType();
  +                             if (pos != 0)
  +                             {
  +                                     posNodeType = pos->getNodeType();
  +                             }
                        }
                }
        }
  
  
  
  1.87      +49 -7     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.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- XSLTEngineImpl.hpp        6 May 2002 05:31:57 -0000       1.86
  +++ XSLTEngineImpl.hpp        9 Jul 2002 06:19:40 -0000       1.87
  @@ -252,9 +252,6 @@
        getSourceTreeFromInput(const XSLTInputSource&   inputSource);
   
        virtual void
  -     outputToResultTree(const XObject&       xobj);
  -
  -     virtual void
        resolveTopLevelParams(StylesheetExecutionContext&       
executionContext);
   
        virtual XMLParserLiaison&
  @@ -585,32 +582,64 @@
                        XalanDOMString::size_type       length);
   
        /**
  -      * Clone an element with or without children.
  +      * Clone a node to the result tree
  +      *
  +      * @param node      node to clone
  +      * @param cloneTextNodesOnly    if true, only text nodes will be cloned
  +      * @param styleNode     the stylesheet element that generated the clone.
  +      */
  +     void
  +     cloneToResultTree(
  +                     const XalanNode&                        node,
  +                     bool                                            
cloneTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode);
  +
  +     /**
  +      * Clone a node to the result tree
         *
         * @param node                                  node to clone
         * @param nodeType                              the type of the node
         * @param isLiteral                     true if a literal element
         * @param overrideStrip                 false if white space stripping 
should be done
         * @param shouldCloneAttributes true if attributes should be cloned
  +      * @param cloneTextNodesOnly    if true, only text nodes will be cloned
         * @param styleNode                             the stylesheet element 
that generated the clone.
         */
        void
        cloneToResultTree(
  -                     XalanNode&                                      node,
  +                     const XalanNode&                        node,
                        XalanNode::NodeType                     nodeType,
                        bool                                            
isLiteral,
                        bool                                            
overrideStrip,
                        bool                                            
shouldCloneAttributes,
  -                     const ElemTemplateElement*      styleNode = 0);
  +                     bool                                            
cloneTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode);
  +
  +   /**
  +     * Output an object to the result tree by doing the right conversions.
  +     *
  +     * @param value the XObject to output
  +     * @param outputTextNodesOnly if true, only text nodes will be copied
  +     */
  +     void
  +     outputToResultTree(
  +                     const XObject&                          value,
  +                     bool                                            
outputTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode);
   
        /**
         * Given a result tree fragment, walk the tree and output it to the 
result
         * stream.
         *
         * @param theTree result tree fragment
  +      * @param outputTextNodesOnly if true, only text nodes will be copied
  +      * @param styleNode     the stylesheet element that generate the 
fragment.
         */
        void
  -     outputResultTreeFragment(const XObject&         theTree);
  +     outputResultTreeFragment(
  +                     const XObject&                          theTree,
  +                     bool                                            
outputTextNodesOnly,
  +                     const ElemTemplateElement*      styleNode);
   
        /**
         * Retrieve the root stylesheet.
  @@ -1438,6 +1467,19 @@
        BoolVectorType  m_cdataStack;
   
   private:
  +
  +     /**
  +      * Clone a text node to the result tree
  +      *
  +      * @param node                                  node to clone
  +      * @param isLiteral                     true if a literal element
  +      * @param overrideStrip                 false if white space stripping 
should be done
  +      */
  +     void
  +     cloneToResultTree(
  +                     const XalanText&        node,
  +                     bool                            isLiteral,
  +                     bool                            overrideStrip);
   
        /**
         * Determine if any pending attributes is a default
  
  
  
  1.28      +0 -8      xml-xalan/c/src/XSLT/XSLTProcessor.hpp
  
  Index: XSLTProcessor.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTProcessor.hpp,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- XSLTProcessor.hpp 19 Oct 2001 18:42:23 -0000      1.27
  +++ XSLTProcessor.hpp 9 Jul 2002 06:19:40 -0000       1.28
  @@ -212,14 +212,6 @@
        virtual XalanNode*
        getSourceTreeFromInput(const XSLTInputSource&   inputSource) = 0;
   
  -   /**
  -     * Output an object to the result tree by doing the right conversions.
  -     *
  -     * @param obj the XObject to output
  -     */
  -     virtual void
  -     outputToResultTree(const XObject&       xobj) = 0;
  -
        /**
         * Retrieve the root stylesheet.
         * 
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to