| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #if !defined(XALAN_XSLTENGINEIMPL_HEADER_GUARD) |
| #define XALAN_XSLTENGINEIMPL_HEADER_GUARD |
| |
| |
| |
| // Base include file. Must be first. |
| #include "XSLTDefinitions.hpp" |
| |
| |
| |
| // Base class |
| #include "XSLTProcessor.hpp" |
| |
| |
| |
| |
| // Standard library headers |
| #include <cassert> |
| |
| |
| |
| #include <xalanc/XalanDOM/XalanDOMString.hpp> |
| |
| |
| |
| #if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION) |
| #include <xalanc/XPath/XPathProcessor.hpp> |
| #endif |
| |
| |
| |
| #include <xalanc/Include/XalanMemMgrAutoPtr.hpp> |
| #include <xalanc/Include/XalanMap.hpp> |
| |
| |
| |
| #include <xalanc/PlatformSupport/AttributeListImpl.hpp> |
| #include <xalanc/PlatformSupport/DOMStringHelper.hpp> |
| #include <xalanc/PlatformSupport/PrefixResolver.hpp> |
| |
| |
| |
| #include <xalanc/DOMSupport/XalanNamespacesStack.hpp> |
| |
| |
| |
| #include <xalanc/XPath/Function.hpp> |
| |
| |
| |
| #include <xalanc/XPath/XPathConstructionContextDefault.hpp> |
| |
| |
| |
| #include "OutputContextStack.hpp" |
| #include "ProblemListenerDefault.hpp" |
| #include "ResultNamespacesStack.hpp" |
| #include "StylesheetExecutionContext.hpp" |
| #include "XSLTProcessorException.hpp" |
| #include "XalanParamHolder.hpp" |
| |
| |
| |
| XALAN_DECLARE_XERCES_CLASS(InputSource) |
| XALAN_DECLARE_XERCES_CLASS(DocumentHandler) |
| |
| |
| |
| XALAN_CPP_NAMESPACE_BEGIN |
| |
| |
| |
| typedef xercesc::InputSource InputSourceType; |
| typedef xercesc::DocumentHandler DocumentHandlerType; |
| |
| XALAN_USING_XERCES(InputSource) |
| XALAN_USING_XERCES(DocumentHandler) |
| |
| |
| |
| // Forward declarations... |
| class DOMSupport; |
| class GenerateEvent; |
| class PrintWriter; |
| class StylesheetConstructionContext; |
| class StylesheetRoot; |
| class XalanAttr; |
| class XalanSourceTreeDocument; |
| class XalanText; |
| class XMLParserLiaison; |
| class XObject; |
| class XPathEnvSupport; |
| class XPathFactory; |
| class XPathProcessor; |
| class XSLTResultTarget; |
| |
| |
| |
| /** |
| * It's the responsibility of the XSLTEngineImpl class, collaborating with the |
| * XML parser liaison, the DOM, and the XPath engine, to transform a source |
| * tree of nodes into a result tree according to instructions and templates |
| * specified by a stylesheet tree. The process method is the primary |
| * public entry points. |
| * |
| * |
| * If you reuse the processor instance, you should call reset() between calls. |
| * |
| */ |
| |
| class XALAN_XSLT_EXPORT XSLTEngineImpl : public XSLTProcessor, public PrefixResolver |
| { |
| public: |
| |
| struct LessXalanDOMStringPointers |
| { |
| bool |
| operator()( |
| const XalanDOMString* theLHS, |
| const XalanDOMString* theRHS) const |
| { |
| if (theLHS == 0 && theRHS != 0) |
| { |
| return true; |
| } |
| else if (theRHS == 0) |
| { |
| return false; |
| } |
| else |
| { |
| return theLHS->compare(*theRHS) < 0 ? true : false; |
| } |
| } |
| }; |
| |
| typedef XalanVector<const Locator*> LocatorStack; |
| typedef XalanVector<TraceListener*> TraceListenerVectorType; |
| typedef XalanVector<const XalanDOMString*> XalanDOMStringPointerVectorType; |
| |
| typedef XalanVector<bool> BoolVectorType; |
| |
| struct FindStringPointerFunctor |
| { |
| FindStringPointerFunctor(const XalanDOMString& theString) : |
| m_string(theString) |
| { |
| } |
| |
| bool |
| operator()(const XalanDOMString* theString) const |
| { |
| assert(theString != 0); |
| |
| return *theString == m_string; |
| } |
| |
| private: |
| |
| const XalanDOMString& m_string; |
| }; |
| |
| typedef XalanMemMgrAutoPtr<XPathProcessor> XPathProcessorPtrType; |
| typedef Function::XObjectArgVectorType XObjectArgVectorType; |
| typedef StylesheetExecutionContext::ParamVectorType ParamVectorType; |
| typedef XPathConstructionContext::GetCachedString CCGetCachedString; |
| typedef XPathExecutionContext::GetCachedString ECGetCachedString; |
| |
| typedef XalanMap<XalanDOMString, XalanParamHolder> ParamMapType; |
| |
| // Public members |
| //--------------------------------------------------------------------- |
| |
| /** |
| * Construct an XSL processor that can call back to a XML processor, so it |
| * can handle included files, and the like. You must create a new instance |
| * of the XSLTEngineImpl class each time you run a transformation. |
| * |
| * @param XMLParserLiaison liaison to an object that can help with a |
| * specific parser implementation |
| * @param xpathEnvSupport An XPathEnvSupport instance |
| * @param domSupport A DOMSupport instance for the DOM being used |
| * @param xobjectFactory object responsible for XObject objects |
| * @param xpathFactory object responsible for XPath objects |
| */ |
| XSLTEngineImpl( |
| MemoryManager& theManager, |
| XMLParserLiaison& parserLiaison, |
| XPathEnvSupport& xpathEnvSupport, |
| DOMSupport& domSupport, |
| XObjectFactory& xobjectFactory, |
| XPathFactory& xpathFactory); |
| |
| virtual |
| ~XSLTEngineImpl(); |
| |
| MemoryManager& |
| getMemoryManager() const |
| { |
| return m_xpathConstructionContext.getMemoryManager(); |
| } |
| |
| MemoryManager& |
| getMemoryManager() |
| { |
| return m_xpathConstructionContext.getMemoryManager(); |
| } |
| |
| /** |
| * Perform initialization of statics -- must be called before any |
| * processing occurs. See class XSLTInit. |
| */ |
| static void |
| initialize(MemoryManager& theManager); |
| |
| /** |
| * Perform termination of statics. See class XSLTInit. |
| */ |
| static void |
| terminate(); |
| |
| // These methods are inherited from XSLTProcessor ... |
| |
| virtual void |
| problem( |
| eSource source, |
| eClassification classification, |
| const XalanDOMString& msg, |
| const Locator* locator, |
| const XalanNode* sourceNode); |
| |
| virtual void |
| problem( |
| eSource source, |
| eClassification classification, |
| const XalanDOMString& msg, |
| const XalanNode* sourceNode); |
| |
| virtual void |
| process( |
| const XSLTInputSource& inputSource, |
| const XSLTInputSource& stylesheetSource, |
| XSLTResultTarget& outputTarget, |
| StylesheetConstructionContext& constructionContext, |
| StylesheetExecutionContext& executionContext); |
| |
| virtual void |
| process( |
| const XSLTInputSource& inputSource, |
| XSLTResultTarget& outputTarget, |
| StylesheetExecutionContext& executionContext); |
| |
| virtual StylesheetRoot* |
| processStylesheet( |
| const XSLTInputSource& stylesheetSource, |
| StylesheetConstructionContext& constructionContext); |
| |
| virtual StylesheetRoot* |
| processStylesheet( |
| const XalanDOMString& xsldocURLString, |
| StylesheetConstructionContext& constructionContext); |
| |
| virtual XalanNode* |
| getSourceTreeFromInput(const XSLTInputSource& inputSource); |
| |
| virtual void |
| resolveTopLevelParams(StylesheetExecutionContext& executionContext); |
| |
| virtual XMLParserLiaison& |
| getXMLParserLiaison() const; |
| |
| virtual void |
| getUniqueNamespaceValue(XalanDOMString& theValue); |
| |
| virtual void |
| setStylesheetParam( |
| const XalanDOMString& key, |
| const XalanDOMString& expression); |
| |
| virtual void |
| setStylesheetParam( |
| const XalanDOMString& key, |
| XObjectPtr value); |
| |
| virtual void |
| clearStylesheetParams(); |
| |
| virtual FormatterListener* |
| getFormatterListener() const; |
| |
| virtual void |
| setFormatterListener(FormatterListener* flistener); |
| |
| // Trace-related functions... |
| |
| virtual size_type |
| getTraceListeners() const; |
| |
| virtual void |
| addTraceListener(TraceListener* tl); |
| |
| virtual void |
| removeTraceListener(TraceListener* tl); |
| |
| virtual void |
| fireGenerateEvent(const GenerateEvent& ge); |
| |
| virtual void |
| fireTraceEvent(const TracerEvent& te); |
| |
| virtual void |
| fireSelectEvent(const SelectionEvent& se); |
| |
| virtual bool |
| getTraceSelects() const; |
| |
| virtual void |
| setTraceSelects(bool b); |
| |
| void |
| traceSelect( |
| StylesheetExecutionContext& executionContext, |
| const ElemTemplateElement& theTemplate, |
| const NodeRefListBase& nl, |
| const XPath* xpath) const; |
| |
| virtual void |
| setQuietConflictWarnings(bool b); |
| |
| virtual void |
| setDiagnosticsOutput(PrintWriter* pw); |
| |
| |
| // Inherited from PrefixResolver... |
| |
| /** |
| * Retrieve a namespace corresponding to a prefix. This assumes that |
| * the PrevixResolver hold's its own namespace context, or is a namespace |
| * context itself. |
| * |
| * @param prefix Prefix to resolve |
| * @return namespace that prefix resolves to, or null if prefix is not found |
| */ |
| virtual const XalanDOMString* |
| getNamespaceForPrefix(const XalanDOMString& prefix) const; |
| |
| /** |
| * Retrieve the base URI for the resolver. |
| * |
| * @return URI string |
| */ |
| virtual const XalanDOMString& |
| getURI() const; |
| |
| /** |
| * Read in the XML file, either producing a Document or calling SAX events, |
| * and register the document in a table. If the document has already been |
| * read in, it will not be reparsed. |
| * |
| * @param urlString location of the XML |
| * @param docHandler pointer to SAX event handler |
| * @param docToRegister if using a SAX event handler, the object to register in the source docs table. |
| * @return document object, which represents the parsed XML |
| * @exception SAXException |
| */ |
| XalanDocument* |
| parseXML( |
| const XalanDOMString& urlString, |
| DocumentHandler* docHandler, |
| XalanDocument* docToRegister, |
| ErrorHandler* theErrorHandler = 0); |
| |
| /** |
| * Read in the XML file, either producing a Document or calling SAX events, |
| * and register the document in a table. If the document has already been |
| * read in, it will not be reparsed. |
| * |
| * @param inputSource location of the XML |
| * @param docHandler pointer to SAX event handler |
| * @param docToRegister if using a SAX event handler, the object to register in the source docs table. |
| * @return document object, which represents the parsed XML |
| * @exception SAXException |
| */ |
| XalanDocument* |
| parseXML( |
| const InputSource& inputSource, |
| DocumentHandler* docHandler, |
| XalanDocument* docToRegister, |
| ErrorHandler* theErrorHandler = 0); |
| |
| /** |
| * Reset the state of the XSL processor by reading in a new XSL stylesheet |
| * from a processing instruction. |
| * |
| * @param xslURLString valid URI to an XSL stylesheet |
| * @param fragBase base of tree if URI represents document |
| * fragment |
| * @param xmlBaseIdent base identifier for stylesheet URI |
| * @param isRoot true if stylesheet is root of tree |
| * @param constructionContext context for construction of object |
| * @return pointer to stylesheet |
| */ |
| Stylesheet* |
| getStylesheetFromPIURL( |
| const XalanDOMString& xslURLString, |
| XalanNode& fragBase, |
| const XalanDOMString& xmlBaseIdent, |
| bool isRoot, |
| StylesheetConstructionContext& constructionContext); |
| |
| /** |
| * Flush the pending element. |
| */ |
| void |
| flushPending(); |
| |
| /** |
| * Add a namespace declaration to the namespace stack |
| * |
| * @param prefix namespace prefix |
| * @param namespaceVal value of namespace |
| */ |
| void |
| addResultNamespaceDecl( |
| const XalanDOMString& prefix, |
| const XalanDOMString& namespaceVal) |
| { |
| addResultNamespaceDecl( |
| prefix, |
| namespaceVal.c_str(), |
| namespaceVal.length()); |
| } |
| |
| /** |
| * Add a namespace declaration to the namespace stack |
| * |
| * @param prefix namespace prefix |
| * @param namespaceVal value of namespace |
| * @param len length of namespace |
| */ |
| void |
| addResultNamespaceDecl( |
| const XalanDOMString& prefix, |
| const XalanDOMChar* namespaceVal, |
| size_type len) |
| { |
| m_resultNamespacesStack.addDeclaration( |
| prefix, |
| namespaceVal, |
| len); |
| } |
| |
| /** |
| * Add attribute to attribute list, and if it is a namespace, add it to the |
| * namespaces stack. |
| * |
| * @param attList attribute list added to |
| * @param aname name of attribute |
| * @param value value of attribute |
| * @param fromCopy true if the attribute is being copied from the source tree |
| * @param locator The Locator for reporting errors. |
| */ |
| void |
| addResultAttribute( |
| AttributeListImpl& attList, |
| const XalanDOMString& aname, |
| const XalanDOMString& value, |
| bool fromCopy = false, |
| const Locator* locator = 0) |
| { |
| addResultAttribute( |
| attList, |
| aname, |
| value.c_str(), |
| fromCopy, |
| locator); |
| } |
| |
| /** |
| * Add attribute to attribute list, and if it is a namespace, add it to the |
| * namespaces stack. |
| * |
| * @param attList attribute list added to |
| * @param aname name of attribute |
| * @param value value of attribute |
| * @param fromCopy true if the attribute is being copied from the source tree |
| * @param locator The Locator for reporting errors. |
| */ |
| void |
| addResultAttribute( |
| AttributeListImpl& attList, |
| const XalanDOMString& aname, |
| const XalanDOMChar* value, |
| bool fromCopy = false, |
| const Locator* locator = 0) |
| { |
| addResultAttribute( |
| attList, |
| aname, |
| value, |
| length(value), |
| fromCopy, |
| locator); |
| } |
| |
| /** |
| * Add attribute to attribute list, and if it is a namespace, add it to the |
| * namespaces stack. |
| * |
| * @param attList attribute list added to |
| * @param aname name of attribute |
| * @param value value of attribute |
| * @param theLength The length of the value |
| * @param fromCopy true if the attribute is being copied from the source tree |
| * @param locator The Locator for reporting errors. |
| */ |
| void |
| addResultAttribute( |
| AttributeListImpl& attList, |
| const XalanDOMString& aname, |
| const XalanDOMChar* value, |
| size_type theLength, |
| bool fromCopy = false, |
| const Locator* locator = 0); |
| |
| /** |
| * Add attribute to pending attributes list, and if it is a namespace, add |
| * it to the namespaces stack. |
| * |
| * @param aname name of attribute |
| * @param value value of attribute |
| * @param fromCopy true if the attribute is being copied from the source tree |
| * @param locator The Locator for reporting errors. |
| */ |
| void |
| addResultAttribute( |
| const XalanDOMString& aname, |
| const XalanDOMChar* value, |
| bool fromCopy = false, |
| const Locator* locator = 0) |
| { |
| assert(m_outputContextStack.empty() == false); |
| |
| addResultAttribute( |
| getPendingAttributesImpl(), |
| aname, |
| value, |
| fromCopy, |
| locator); |
| } |
| |
| /** |
| * Add attribute to pending attributes list, and if it is a namespace, add |
| * it to the namespaces stack. |
| * |
| * @param aname name of attribute |
| * @param value value of attribute |
| * @param fromCopy true if the attribute is being copied from the source tree |
| * @param locator The Locator for reporting errors. |
| */ |
| void |
| addResultAttribute( |
| const XalanDOMString& aname, |
| const XalanDOMString& value, |
| bool fromCopy = false, |
| const Locator* locator = 0) |
| { |
| assert(m_outputContextStack.empty() == false); |
| |
| addResultAttribute( |
| getPendingAttributesImpl(), |
| aname, |
| value, |
| fromCopy, |
| locator); |
| } |
| |
| /** |
| * Report an error copying a duplicate namespace node. |
| * |
| * @param theName The name of the node. |
| */ |
| void |
| reportDuplicateNamespaceNodeError( |
| const XalanDOMString& theName, |
| const Locator* locator); |
| |
| void |
| setDocumentLocator(const Locator* locator); |
| |
| void |
| startDocument(); |
| |
| void |
| endDocument(); |
| |
| void |
| startElement( |
| const XalanDOMChar* name, |
| AttributeListType& atts); |
| |
| void |
| endElement(const XalanDOMChar* name); |
| |
| void |
| characters ( |
| const XalanDOMChar* ch, |
| size_type length); |
| |
| void |
| ignorableWhitespace( |
| const XalanDOMChar* ch, |
| size_type length); |
| |
| void |
| processingInstruction( |
| const XalanDOMChar* target, |
| const XalanDOMChar* data); |
| |
| void |
| resetDocument(); |
| |
| /** |
| * Receive notification of character data. |
| * |
| * @param ch pointer to characters from the XML document |
| * @param start startng offset in 'ch' array |
| * @param length number of characters to read from the array |
| */ |
| void |
| characters( |
| const XalanDOMChar* ch, |
| size_type start, |
| size_type length); |
| |
| /** |
| * Send character data from the node to the result tree. |
| * |
| * @param node The node to send. |
| */ |
| void |
| characters(const XalanNode& node); |
| |
| /** |
| * Send character data from an XObject to the result tree. |
| * |
| * @param node The xobject to send. |
| */ |
| void |
| characters(const XObjectPtr& xobject); |
| |
| /** |
| * Receive notification of the beginning of an element with an empty |
| * attribute list |
| * |
| * @param name element type name |
| */ |
| void |
| startElement(const XalanDOMChar* name); |
| |
| /** |
| * Receive notification of character data. If available, when the |
| * disable-output-escaping attribute is used, output raw text without |
| * escaping. |
| * |
| * @param ch pointer to characters from the XML document |
| * @param start start position in the array |
| * @param length number of characters to read from the array |
| */ |
| void |
| charactersRaw( |
| const XalanDOMChar* ch, |
| size_type start, |
| size_type length); |
| |
| /** |
| * Send raw character data from the node to the result tree. |
| * |
| * @param node The node to send. |
| */ |
| void |
| charactersRaw(const XalanNode& node); |
| |
| /** |
| * Send raw character data from an XObject to the result tree. |
| * |
| * @param node The xobject to send. |
| */ |
| void |
| charactersRaw(const XObjectPtr& xobject); |
| |
| /** |
| * Called when a Comment is to be constructed. |
| * |
| * @param data pointer to comment data |
| */ |
| void |
| comment(const XalanDOMChar* data); |
| |
| /** |
| * Receive notification of a entityReference. |
| * |
| * @param data pointer to characters from the XML document |
| * @exception SAXException |
| */ |
| void |
| entityReference(const XalanDOMChar* data); |
| |
| /** |
| * Receive notification of cdata. |
| * |
| * @param ch pointer to characters from the XML document |
| * @param start start position in the array |
| * @param length number of characters to read from the array |
| */ |
| void |
| cdata( |
| const XalanDOMChar* ch, |
| size_type start, |
| size_type length); |
| |
| /** |
| * Clone a node to the result tree |
| * |
| * @param node node to clone |
| * @param cloneTextNodesOnly if true, only text nodes will be cloned |
| * @param locator the Locator for the event, if any. |
| */ |
| void |
| cloneToResultTree( |
| const XalanNode& node, |
| bool cloneTextNodesOnly, |
| const Locator* locator); |
| |
| /** |
| * Clone a node to the result tree |
| * |
| * @param node node to clone |
| * @param nodeType the type of the node |
| * @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 locator the Locator for the event, if any. |
| */ |
| void |
| cloneToResultTree( |
| const XalanNode& node, |
| XalanNode::NodeType nodeType, |
| bool overrideStrip, |
| bool shouldCloneAttributes, |
| bool cloneTextNodesOnly, |
| const Locator* locator); |
| |
| /** |
| * 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 |
| * @param locator the Locator for the event, if any. |
| */ |
| void |
| outputToResultTree( |
| const XObject& value, |
| bool outputTextNodesOnly, |
| const Locator* locator); |
| |
| /** |
| * 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 locator the Locator for the event, if any. |
| */ |
| void |
| outputResultTreeFragment( |
| const XObject& theTree, |
| bool outputTextNodesOnly, |
| const Locator* locator) |
| { |
| outputResultTreeFragment( |
| theTree.rtree(), |
| outputTextNodesOnly, |
| locator); |
| } |
| |
| /** |
| * 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 locator the Locator for the event, if any. |
| */ |
| void |
| outputResultTreeFragment( |
| const XalanDocumentFragment& theTree, |
| bool outputTextNodesOnly, |
| const Locator* locator); |
| |
| /** |
| * Retrieve the root stylesheet. |
| * |
| * @return pointer to root stylesheet |
| */ |
| virtual const StylesheetRoot* |
| getStylesheetRoot() const; |
| |
| /** |
| * Set the root stylesheet. |
| * |
| * @param theStylesheet pointer to new root stylesheet |
| */ |
| virtual void |
| setStylesheetRoot(const StylesheetRoot* theStylesheet); |
| |
| /** |
| * Set the execution context. |
| * |
| * @param theExecutionContext pointer to new execution context. |
| */ |
| virtual void |
| setExecutionContext(StylesheetExecutionContext* theExecutionContext); |
| |
| /** |
| * Retrieve the URI for the current XSL namespace, for example, |
| * "http://www.w3.org/1999/XSL/Transform" |
| * |
| * @return URI string |
| */ |
| static const XalanDOMString& |
| getXSLNameSpaceURL() |
| { |
| return s_XSLNameSpaceURL; |
| } |
| |
| /** |
| * Special Xalan namespace for built-in extensions. |
| * |
| * @return Xalan namespace for extensions |
| */ |
| static const XalanDOMString& |
| getXalanXSLNameSpaceURL() |
| { |
| return s_XalanNamespaceURL; |
| } |
| |
| /** |
| * Whether to warn about pattern match conflicts. |
| * |
| * @return true to not warn about pattern match conflicts |
| */ |
| bool |
| getQuietConflictWarnings() const |
| { |
| return m_quietConflictWarnings; |
| } |
| |
| /** |
| * Retrieve the result namespace corresponding to a prefix. |
| * |
| * @param prefix prefix for namespace |
| * @return string for namespace URI |
| */ |
| const XalanDOMString* |
| getResultNamespaceForPrefix(const XalanDOMString& prefix) const; |
| |
| /** |
| * Retrieve the result prefix corresponding to a namespace. |
| * |
| * @param theNamespace namespace for prefix |
| * @return string for namespace prefix |
| */ |
| const XalanDOMString* |
| getResultPrefixForNamespace(const XalanDOMString& theNamespace) const; |
| |
| /** |
| * Determine whether or not a prefix is in use on the pending element or |
| * the pending attributes. |
| * |
| * @param thePrefix prefix for namespace |
| * |
| * @return true if the prefix is in use, false if not. |
| */ |
| bool |
| isPendingResultPrefix(const XalanDOMString& thePrefix) const; |
| |
| /** |
| * Evaluate an xpath string and return the result as a numberic score. |
| * |
| * @param str string to evaluate |
| * @param context context node |
| * @param executionContext current execution context |
| * @return score number, higher representing better match |
| */ |
| double |
| evalMatchPatternStr( |
| const XalanDOMString& str, |
| XalanNode* context, |
| XPathExecutionContext& executionContext); |
| |
| /** |
| * Create and initialize an xpath and return it. |
| * |
| * @param str string for XPath |
| * @param resolver resolver for namespace resolution |
| * @return pointer to XPath created |
| */ |
| const XPath* |
| createMatchPattern( |
| const XalanDOMString& str, |
| const PrefixResolver& resolver); |
| |
| /** |
| * Return the xpath created by createXPath() or |
| * createMatchPattern(). |
| * |
| * @param xpath The XPath to return. |
| */ |
| void |
| returnXPath(const XPath* xpath); |
| |
| /** |
| * Copy XMLNS: attributes in if not already in scope. |
| * |
| * @param src source node |
| */ |
| void |
| copyNamespaceAttributes(const XalanNode& src); |
| |
| /** |
| * Evaluate an xpath string and return the result. |
| * |
| * @param str string to evaluate |
| * @param executionContext current execution context |
| * @return pointer to XObject result |
| */ |
| const XObjectPtr |
| evalXPathStr( |
| const XalanDOMString& str, |
| XPathExecutionContext& executionContext); |
| |
| /** |
| * Evaluate an xpath string and return the result. |
| * |
| * @param str string to evaluate |
| * @param contextNode context node |
| * @param prefixResolver prefix resolver to use |
| * @param executionContext current execution context |
| * @return pointer to XObject result |
| */ |
| const XObjectPtr |
| evalXPathStr( |
| const XalanDOMString& str, |
| XalanNode* contextNode, |
| const PrefixResolver& prefixResolver, |
| XPathExecutionContext& executionContext); |
| |
| /** |
| * Evaluate an xpath string and return the result. |
| * |
| * @param str string to evaluate |
| * @param contextNode context node |
| * @param prefixResolver prefix resolver to use |
| * @param executionContext current execution context |
| * @return pointer to XObject result |
| */ |
| const XObjectPtr |
| evalXPathStr( |
| const XalanDOMString& str, |
| XalanNode* contextNode, |
| const XalanElement& prefixResolver, |
| XPathExecutionContext& executionContext); |
| |
| /** |
| * Copy an attribute to an AttributeListImpl. |
| * |
| * @param attrName The name of the attribute |
| * @param attrValue The value of the attribute |
| * @param attrList The attribute list added to |
| */ |
| void |
| copyAttributeToTarget( |
| const XalanDOMString& attrName, |
| const XalanDOMString& attrValue, |
| AttributeListImpl& attrList); |
| |
| /** |
| * Get the factory for making xpaths. |
| * |
| * @return XPath factory object |
| */ |
| XPathFactory& |
| getXPathFactory() |
| { |
| return m_xpathFactory; |
| } |
| |
| /** |
| * Get the XPath processor object. |
| * |
| * @return XPathProcessor interface being used |
| */ |
| XPathProcessor& |
| getXPathProcessor() |
| { |
| return *m_xpathProcessor.get(); |
| } |
| |
| /** |
| * Reset the state. This needs to be called after a process() call |
| * is invoked, if the processor is to be used again. |
| */ |
| virtual void |
| reset(); |
| |
| /** |
| * Retrieve the XPath environment support object |
| * |
| * @return XPath environment support object |
| */ |
| XPathEnvSupport& |
| getXPathEnvSupport() |
| { |
| return m_xpathEnvSupport; |
| } |
| |
| /** |
| * Set the problem listener property. The XSL class can have a single |
| * listener that can be informed of errors and warnings, and can normally |
| * control if an exception is thrown or not (or the problem listeners can |
| * throw their own RuntimeExceptions). |
| * |
| * @param l pointer to ProblemListener interface |
| */ |
| void |
| setProblemListener(ProblemListener* l) |
| { |
| m_problemListener = l; |
| } |
| |
| /** |
| * Get the problem listener property. The XSL class can have a single |
| * listener that can be informed of errors and warnings, and can normally |
| * control if an exception is thrown or not (or the problem listeners can |
| * throw their own RuntimeExceptions). |
| * |
| * @return pointer to ProblemListener interface |
| */ |
| ProblemListener* |
| getProblemListener() const |
| { |
| return m_problemListener; |
| } |
| |
| /* |
| * Push a new output context using the provided FormatterListener. |
| * |
| * @param A pointer to the FormatterListener instance for the new context. |
| */ |
| void |
| pushOutputContext(FormatterListener* theListener) |
| { |
| m_outputContextStack.pushContext(theListener); |
| } |
| |
| /* |
| * Pop the current output context. |
| */ |
| void |
| popOutputContext() |
| { |
| m_outputContextStack.popContext(); |
| } |
| |
| /* |
| * See if there is a pending start document event waiting. |
| * @return true if there is a start document event waiting. |
| */ |
| bool |
| getHasPendingStartDocument() const |
| { |
| return getHasPendingStartDocumentImpl(); |
| } |
| |
| /* |
| * Set the pending start document event state. |
| * @param the new value |
| */ |
| void |
| setHasPendingStartDocument(bool b) |
| { |
| setHasPendingStartDocumentImpl(b); |
| } |
| |
| /* |
| * See if a pending start document event must be flushed. |
| * @return true if the event must be flushed. |
| */ |
| bool |
| getMustFlushPendingStartDocument() const |
| { |
| return getMustFlushPendingStartDocumentImpl(); |
| } |
| |
| /* |
| * Set the pending start document event flush state. |
| * @param the new value |
| */ |
| void |
| setMustFlushPendingStartDocument(bool b) |
| { |
| setMustFlushPendingStartDocumentImpl(b); |
| } |
| |
| /** |
| * Get the list of attributes yet to be processed |
| * |
| * @return attribute list |
| */ |
| const AttributeListType& |
| getPendingAttributes() const |
| { |
| return getPendingAttributesImpl(); |
| } |
| |
| /** |
| * Set the list of attributes yet to be processed |
| * |
| * @param pendingAttributes The attribute list |
| */ |
| void |
| setPendingAttributes(const AttributeListType& pendingAttributes) |
| { |
| getPendingAttributesImpl() = pendingAttributes; |
| } |
| |
| /** |
| * Replace the contents of a pending attribute. |
| * |
| * @param theName name of attribute |
| * @param theNewType type of attribute |
| * @param theNewValue new value of attribute |
| */ |
| void |
| replacePendingAttribute( |
| const XalanDOMChar* theName, |
| const XalanDOMChar* theNewType, |
| const XalanDOMChar* theNewValue) |
| { |
| // Remove the old attribute, then add the new one. AttributeListImpl::addAttribute() |
| // does this for us. |
| getPendingAttributesImpl().addAttribute(theName, theNewType, theNewValue); |
| } |
| |
| bool |
| isElementPending() const |
| { |
| return !getPendingElementNameImpl().empty(); |
| } |
| |
| /** |
| * Retrieve name of the pending element currently being processed. |
| * |
| * @return element name |
| */ |
| const XalanDOMString& |
| getPendingElementName() const |
| { |
| return getPendingElementNameImpl(); |
| } |
| |
| /** |
| * Changes the currently pending element name. |
| * |
| * @param elementName new name of element |
| */ |
| void |
| setPendingElementName(const XalanDOMString& elementName) |
| { |
| setPendingElementNameImpl(elementName); |
| } |
| |
| void |
| setPendingElementName(const XalanDOMChar* elementName) |
| { |
| setPendingElementNameImpl(elementName); |
| } |
| |
| /** |
| * Get the locator from the top of the locator stack. |
| * |
| * @return A pointer to the Locator, or 0 if there is nothing on the stack. |
| */ |
| const Locator* |
| getLocatorFromStack() const |
| { |
| return m_stylesheetLocatorStack.empty() == true ? 0 : m_stylesheetLocatorStack.back(); |
| } |
| |
| /** |
| * Push a locator on to the locator stack. |
| * |
| * @param A pointer to the Locator to push. |
| */ |
| void |
| pushLocatorOnStack(const Locator* locator) |
| { |
| m_stylesheetLocatorStack.push_back(locator); |
| } |
| |
| /** |
| * Pop the locator from the top of the locator stack. |
| */ |
| void |
| popLocatorStack() |
| { |
| if (m_stylesheetLocatorStack.empty() == false) |
| { |
| m_stylesheetLocatorStack.pop_back(); |
| } |
| } |
| |
| protected: |
| |
| /** |
| * Get the list of attributes yet to be processed |
| * |
| * @return attribute list |
| */ |
| const AttributeListImpl& |
| getPendingAttributesImpl() const |
| { |
| return m_outputContextStack.getPendingAttributes(); |
| } |
| |
| /** |
| * Get the list of attributes yet to be processed |
| * |
| * @return attribute list |
| */ |
| AttributeListImpl& |
| getPendingAttributesImpl() |
| { |
| return m_outputContextStack.getPendingAttributes(); |
| } |
| |
| /** |
| * Set the list of attributes yet to be processed |
| * |
| * @param pendingAttributes The attribute list |
| */ |
| void |
| setPendingAttributesImpl(const AttributeListType& pendingAttributes) |
| { |
| getPendingAttributesImpl() = pendingAttributes; |
| } |
| |
| /** |
| * Retrieve name of the pending element currently being processed. |
| * |
| * @return element name |
| */ |
| const XalanDOMString& |
| getPendingElementNameImpl() const |
| { |
| return m_outputContextStack.getPendingElementName(); |
| } |
| |
| /** |
| * Retrieve name of the pending element currently being processed. |
| * |
| * @return element name |
| */ |
| XalanDOMString& |
| getPendingElementNameImpl() |
| { |
| return m_outputContextStack.getPendingElementName(); |
| } |
| |
| /** |
| * Changes the currently pending element name. |
| * |
| * @param elementName new name of element |
| */ |
| void |
| setPendingElementNameImpl(const XalanDOMString& elementName) |
| { |
| m_outputContextStack.getPendingElementName() = elementName; |
| } |
| |
| /** |
| * Changes the currently pending element name. |
| * |
| * @param elementName new name of element |
| */ |
| void |
| setPendingElementNameImpl(const XalanDOMChar* elementName) |
| { |
| assert(elementName != 0); |
| |
| m_outputContextStack.getPendingElementName() = elementName; |
| } |
| |
| /* |
| * See if there is a pending start document event waiting. |
| * @return true if there is a start document event waiting. |
| */ |
| bool |
| getHasPendingStartDocumentImpl() const |
| { |
| return m_outputContextStack.getHasPendingStartDocument(); |
| } |
| |
| /* |
| * Set the pending start document event state. |
| * @param the new value |
| */ |
| void |
| setHasPendingStartDocumentImpl(bool b) |
| { |
| m_outputContextStack.getHasPendingStartDocument() = b; |
| } |
| |
| /* |
| * See if a pending start document event must be flushed. |
| * @return true if the event must be flushed. |
| */ |
| bool |
| getMustFlushPendingStartDocumentImpl() const |
| { |
| return m_outputContextStack.getMustFlushPendingStartDocument(); |
| } |
| |
| /* |
| * Set the pending start document event flush state. |
| * @param the new value |
| */ |
| void |
| setMustFlushPendingStartDocumentImpl(bool b) |
| { |
| m_outputContextStack.getMustFlushPendingStartDocument() = b; |
| } |
| |
| FormatterListener* |
| getFormatterListenerImpl() const |
| { |
| return m_outputContextStack.getFormatterListener(); |
| } |
| |
| void |
| setFormatterListenerImpl(FormatterListener* flistener) |
| { |
| m_outputContextStack.getFormatterListener() = flistener; |
| } |
| |
| /** |
| * The namespace that the result tree conforms to. A null value |
| * indicates that result-ns is not used and there is no checking. |
| * A empty string indicates that the result tree conforms to the |
| * default namespace. |
| */ |
| XalanDOMString m_resultNameSpacePrefix; |
| |
| /** |
| * The URL that belongs to the result namespace. |
| */ |
| XalanDOMString m_resultNameSpaceURL; |
| |
| |
| /** |
| * Copy the attributes from the XSL element to the created |
| * output element. |
| */ |
| void |
| copyAttributesToAttList( |
| const XalanNode& node, |
| AttributeListImpl& attList); |
| |
| // Factory for creating xpaths. |
| XPathFactory& m_xpathFactory; |
| |
| // Factory for creating xobjects |
| XObjectFactory& m_xobjectFactory; |
| |
| // The query/pattern-matcher object. |
| const XPathProcessorPtrType m_xpathProcessor; |
| |
| /** |
| * Stack of Booleans to keep track of if we should be outputting |
| * cdata instead of escaped text. |
| */ |
| BoolVectorType m_cdataStack; |
| |
| private: |
| |
| /** |
| * Issue a warning that only text nodes can be copied. |
| * |
| * @param sourceNode node in source where error occurred |
| * @param locator The Locator to use, if any. |
| */ |
| void |
| warnCopyTextNodesOnly( |
| const XalanNode* sourceNode, |
| const Locator* locator); |
| |
| /** |
| * Clone a text node to the result tree |
| * |
| * @param node node to clone |
| * @param overrideStrip false if white space stripping should be done |
| */ |
| void |
| cloneToResultTree( |
| const XalanText& node, |
| bool overrideStrip); |
| |
| /** |
| * Determine if any pending attributes is a default |
| * namespace. |
| */ |
| bool |
| pendingAttributesHasDefaultNS() const; |
| |
| void |
| addResultNamespace( |
| const XalanDOMString& thePrefix, |
| const XalanDOMString& theName, |
| const XalanNode& theNode, |
| AttributeListImpl& thePendingAttributes, |
| bool fOnlyIfPrefixNotPresent); |
| |
| void |
| addResultNamespace( |
| const XalanNode& theNode, |
| AttributeListImpl& thePendingAttributes, |
| bool fOnlyIfPrefixNotPresent = false); |
| |
| /** |
| * The top of this stack should contain the currently processed |
| * stylesheet SAX locator object. |
| */ |
| LocatorStack m_stylesheetLocatorStack; |
| |
| /** |
| * The XSL class can have a single listener that can be informed |
| * of errors and warnings, and can normally control if an exception |
| * is thrown or not (or the problem listeners can throw their |
| * own RuntimeExceptions). |
| */ |
| ProblemListenerDefault m_defaultProblemListener; |
| |
| ProblemListener* m_problemListener; |
| |
| /** |
| * The root of a linked set of stylesheets. |
| */ |
| const StylesheetRoot* m_stylesheetRoot; |
| |
| /** |
| * The namespace that we must match as a minimum for XSLT. |
| */ |
| static const XalanDOMString& s_XSLNameSpaceURL; //"http://www.w3.org/1999/XSL/Transform" |
| |
| /** |
| * Special Xalan namespace for built-in extensions. |
| */ |
| static const XalanDOMString& s_XalanNamespaceURL; // "http://xml.apache.org/xalan" |
| |
| /** |
| * Prefix to use when generating unique namespaces. |
| */ |
| static const XalanDOMString& s_uniqueNamespacePrefix; |
| |
| /** |
| * If this is set to true, selects will be traced |
| */ |
| bool m_traceSelects; |
| |
| /** |
| * If this is set to true, do not warn about pattern |
| * match conflicts. |
| */ |
| bool m_quietConflictWarnings; |
| |
| /* |
| * A stream to print diagnostics to. |
| */ |
| PrintWriter* m_diagnosticsPrintWriter; |
| |
| /** |
| * List of listeners who are interested in tracing what's |
| * being generated. |
| */ |
| TraceListenerVectorType m_traceListeners; |
| |
| void |
| problem( |
| const XalanDOMString& msg, |
| ProblemListener::eClassification classification, |
| const XalanNode* sourceNode, |
| const ElemTemplateElement* styleNode) const; |
| |
| void |
| problem( |
| const XalanDOMString& msg, |
| ProblemListener::eClassification classification, |
| const Locator& locator, |
| const XalanNode* sourceNode) const; |
| |
| void |
| problem( |
| const XalanDOMString& msg, |
| ProblemListener::eClassification classification) const; |
| |
| //========================================================== |
| // SECTION: Function to do with attribute handling |
| //========================================================== |
| |
| /** |
| * This is used whenever a unique namespace is needed. |
| */ |
| unsigned long m_uniqueNSValue; |
| |
| ParamVectorType m_topLevelParams; |
| |
| public: |
| |
| /** |
| * Reset the vector of top level parameters |
| */ |
| void |
| clearTopLevelParams() |
| { |
| m_topLevelParams.clear(); |
| } |
| |
| private: |
| |
| bool |
| generateCDATASection() const |
| { |
| if (m_hasCDATASectionElements == false) |
| { |
| return false; |
| } |
| else |
| { |
| assert(m_cdataStack.empty() == false); |
| |
| return m_cdataStack.back(); |
| } |
| } |
| |
| void |
| doFlushPending() |
| { |
| setMustFlushPendingStartDocument(true); |
| |
| flushPending(); |
| } |
| |
| /** |
| * Tell if a given element name should output its text |
| * as cdata. |
| * |
| * @param elementName name of element |
| * @return true if it should output as cdata |
| */ |
| bool |
| isCDataResultElem(const XalanDOMString& elementName); |
| |
| void |
| fireCharacterGenerateEvent( |
| const XalanNode& theNode, |
| bool isCDATA); |
| |
| void |
| fireCharacterGenerateEvent( |
| const XObjectPtr& theXObject, |
| bool isCDATA); |
| |
| void |
| fireCharacterGenerateEvent( |
| const XalanDOMString& theString, |
| bool isCDATA); |
| |
| void |
| fireCharacterGenerateEvent( |
| const XalanDOMChar* ch, |
| size_type start, |
| size_type length, |
| bool isCDATA); |
| |
| void |
| checkDefaultNamespace( |
| const XalanDOMString& theElementName, |
| const XalanDOMString& theElementNamespaceURI); |
| |
| void |
| error( |
| const XalanDOMString& theMessage, |
| const Locator* theLocator, |
| const XalanNode* theSourceNode); |
| |
| void |
| warn( |
| const XalanDOMString& theMessage, |
| const Locator* theLocator, |
| const XalanNode* theSourceNode); |
| |
| void |
| message( |
| const XalanDOMString& theMessage, |
| const Locator* theLocator, |
| const XalanNode* theSourceNode); |
| |
| // Data members... |
| XMLParserLiaison& m_parserLiaison; |
| |
| XPathEnvSupport& m_xpathEnvSupport; |
| |
| DOMSupport& m_domSupport; |
| |
| /** |
| * Current execution context... |
| */ |
| StylesheetExecutionContext* m_executionContext; |
| |
| /* |
| * Stack of current output contexts... |
| */ |
| OutputContextStack m_outputContextStack; |
| |
| /* |
| * Stack of current result namespaces... |
| */ |
| XalanNamespacesStack m_resultNamespacesStack; |
| |
| /* |
| * Dummy AttributeListImpl |
| */ |
| AttributeListImpl m_dummyAttributesList; |
| |
| XalanDOMString m_scratchString; |
| |
| XalanDOMStringPointerVectorType m_attributeNamesVisited; |
| |
| bool m_hasCDATASectionElements; |
| |
| XPathConstructionContextDefault m_xpathConstructionContext; |
| |
| ParamMapType m_stylesheetParams; |
| |
| static void |
| installFunctions(MemoryManager& theManager); |
| |
| static void |
| uninstallFunctions(); |
| |
| |
| static const XalanDOMString s_emptyString; |
| |
| static const XalanDOMString& s_stylesheetNodeName; |
| static const XalanDOMString& s_typeString; |
| static const XalanDOMString& s_hrefString; |
| static const XalanDOMString& s_piTokenizerString; |
| static const XalanDOMString& s_typeValueString1; |
| static const XalanDOMString& s_typeValueString2; |
| static const XalanDOMString& s_typeValueString3; |
| static const XalanDOMString& s_typeValueString4; |
| |
| // Not implemented... |
| XSLTEngineImpl(const XSLTEngineImpl&); |
| |
| XSLTEngineImpl& |
| operator=(const XSLTEngineImpl&); |
| |
| bool |
| operator==(const XSLTEngineImpl&) const; |
| }; |
| |
| |
| |
| XALAN_CPP_NAMESPACE_END |
| |
| |
| |
| #endif // XALAN_XSLTENGINEIMPL_HEADER_GUARD |