| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xalan" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, International |
| * Business Machines, Inc., http://www.ibm.com. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| * $ Id: $ |
| * |
| */ |
| |
| #include "Stylesheet.hpp" |
| |
| |
| |
| #include <algorithm> |
| |
| |
| |
| #include <sax/AttributeList.hpp> |
| |
| |
| |
| #include <Include/STLHelper.hpp> |
| |
| |
| |
| #include <XalanDOM/XalanDOMException.hpp> |
| |
| |
| |
| #include <DOMSupport/DOMServices.hpp> |
| |
| |
| |
| #include <XMLSupport/XMLParserLiaison.hpp> |
| |
| |
| |
| #include <XPath/ElementPrefixResolverProxy.hpp> |
| #include <XPath/XObject.hpp> |
| #include <XPath/XPath.hpp> |
| #include <XPath/XalanQNameByReference.hpp> |
| |
| |
| |
| #include "Constants.hpp" |
| #include "ElemAttributeSet.hpp" |
| #include "ElemDecimalFormat.hpp" |
| #include "ElemTemplate.hpp" |
| #include "ElemTemplateElement.hpp" |
| #include "ElemVariable.hpp" |
| #include "ExtensionNSHandler.hpp" |
| #include "KeyTable.hpp" |
| #include "StylesheetConstructionContext.hpp" |
| #include "StylesheetExecutionContext.hpp" |
| #include "StylesheetRoot.hpp" |
| |
| |
| |
| const Stylesheet::NamespaceVectorType Stylesheet::s_emptyNamespace; |
| |
| |
| |
| const XalanDOMString Stylesheet::s_emptyString; |
| |
| const XalanQNameByReference Stylesheet::s_emptyQName; |
| |
| const XalanEmptyNamedNodeMap Stylesheet::s_fakeAttributes; |
| |
| |
| |
| Stylesheet::Stylesheet( |
| StylesheetRoot& root, |
| const XalanDOMString& baseIdentifier, |
| StylesheetConstructionContext& constructionContext) : |
| XalanDocument(), |
| PrefixResolver(), |
| m_stylesheetRoot(root), |
| m_baseIdent(baseIdentifier), |
| m_keyDeclarations(), |
| m_XSLTNamespaceURI(constructionContext.getXSLTNamespaceURI()), |
| m_whitespacePreservingElements(), |
| m_whitespaceStrippingElements(), |
| m_imports(), |
| m_importsSize(0), |
| m_namespaces(), |
| m_namespaceDecls(), |
| m_isWrapperless(false), |
| m_wrapperlessTemplate(0), |
| m_extensionNamespaces(), |
| m_firstTemplate(0), |
| m_includeStack(), |
| m_namedTemplates(), |
| m_topLevelVariables(), |
| m_XSLTVerDeclared(1.0L), |
| m_isRoot(&root == this ? true: false), |
| m_patternTable(), |
| m_patternTableEnd(m_patternTable.end()), |
| m_textPatternList(), |
| m_commentPatternList(), |
| m_rootPatternList(), |
| m_piPatternList(), |
| m_nodePatternList(), |
| m_anyPatternList(), |
| m_matchPattern2Container(), |
| m_patternCount(0), |
| m_attributeSets(), |
| m_attributeSetsSize(0), |
| m_surrogateChildren(*this), |
| m_elemDecimalFormats(), |
| m_prefixAliases(), |
| m_namespacesHandler() |
| { |
| if (length(m_baseIdent) == 0) |
| { |
| m_includeStack.push_back(m_baseIdent); |
| } |
| else |
| { |
| try |
| { |
| const XalanDOMString urlString = constructionContext.getURLStringFromString(m_baseIdent); |
| |
| if (length(urlString) != 0) |
| { |
| m_includeStack.push_back(urlString); |
| |
| m_baseIdent = urlString; |
| } |
| } |
| catch(const XMLException&) |
| { |
| // Assume that any exception here relates to get the urlString from |
| // m_baseIdent. We'll assume that it's just a fake base identifier |
| // since the parser will throw the real error if the base identifier |
| // can't be resolved. |
| m_includeStack.push_back(baseIdentifier); |
| } |
| } |
| } |
| |
| |
| |
| Stylesheet::~Stylesheet() |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::for_each; |
| #endif |
| |
| // Clean up all entries in the imports vector. |
| for_each(m_imports.begin(), |
| m_imports.end(), |
| DeleteFunctor<Stylesheet>()); |
| |
| // Clean up the atribute sets vector |
| for_each(m_attributeSets.begin(), |
| m_attributeSets.end(), |
| DeleteFunctor<ElemAttributeSet>()); |
| |
| // Clean up the top-level variables vector |
| for_each(m_topLevelVariables.begin(), |
| m_topLevelVariables.end(), |
| DeleteFunctor<ElemVariable>()); |
| |
| // Clean up the decimal formats vector |
| for_each(m_elemDecimalFormats.begin(), |
| m_elemDecimalFormats.end(), |
| DeleteFunctor<ElemDecimalFormat>()); |
| |
| // Clean up the extension namespaces vector |
| for_each(m_extensionNamespaces.begin(), |
| m_extensionNamespaces.end(), |
| MapValueDeleteFunctor<ExtensionNamespacesMapType>()); |
| |
| delete m_wrapperlessTemplate; |
| |
| delete m_firstTemplate; |
| } |
| |
| |
| |
| void |
| Stylesheet::processKeyElement( |
| ElemTemplateElement* nsContext, |
| const AttributeList& atts, |
| StylesheetConstructionContext& constructionContext) |
| { |
| const XalanDOMChar* nameAttr = 0; |
| XPath* matchAttr = 0; |
| XPath* useAttr = 0; |
| |
| const unsigned int nAttrs = atts.getLength(); |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if (equals(aname, Constants::ATTRNAME_NAME)) |
| { |
| nameAttr = atts.getValue(i); |
| } |
| else if(equals(aname, Constants::ATTRNAME_MATCH)) |
| { |
| matchAttr = |
| constructionContext.createMatchPattern( |
| 0, |
| XalanDOMString(atts.getValue(i)), |
| *nsContext); |
| } |
| else if(equals(aname, Constants::ATTRNAME_USE)) |
| { |
| useAttr = |
| constructionContext.createXPath( |
| 0, |
| atts.getValue(i), |
| *nsContext); |
| } |
| else if (isAttrOK(aname, atts, i, constructionContext) == false) |
| { |
| constructionContext.error( |
| TranscodeFromLocalCodePage("xsl:key, unrecognized keyword '") + |
| aname + |
| TranscodeFromLocalCodePage("'!")); |
| } |
| } |
| |
| if(0 == nameAttr) |
| constructionContext.error(TranscodeFromLocalCodePage("xsl:key requires a ") + Constants::ATTRNAME_NAME + " attribute!"); |
| |
| if(0 == matchAttr) |
| constructionContext.error(TranscodeFromLocalCodePage("xsl:key requires a ") + Constants::ATTRNAME_MATCH + " attribute!"); |
| |
| if(0 == useAttr) |
| constructionContext.error(TranscodeFromLocalCodePage("xsl:key requires a ") + Constants::ATTRNAME_USE + " attribute!"); |
| |
| m_keyDeclarations.push_back(KeyDeclaration(XalanDOMString(nameAttr), *matchAttr, *useAttr)); |
| } |
| |
| |
| |
| void |
| Stylesheet::pushNamespaces(const AttributeList& atts) |
| { |
| const unsigned int nAttrs = atts.getLength(); |
| |
| NamespaceVectorType namespaces; |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| const XalanDOMChar* const value = atts.getValue(i); |
| |
| const bool isPrefix = startsWith(aname, DOMServices::s_XMLNamespaceWithSeparator); |
| |
| if (equals(aname, DOMServices::s_XMLNamespace) || isPrefix) |
| { |
| const XalanDOMString p = isPrefix ? substring(aname, 6) : XalanDOMString(); |
| |
| namespaces.push_back(NameSpace(p, XalanDOMString(value))); |
| } |
| } |
| |
| m_namespaces.push_back(namespaces); |
| } |
| |
| |
| |
| class attrSetCompare |
| { |
| public: |
| |
| attrSetCompare(const ElemAttributeSet& theAttrSet) : |
| m_attrSet(theAttrSet) |
| { |
| } |
| |
| bool |
| operator()(const ElemAttributeSet* theRHS) const |
| { |
| assert(theRHS != 0); |
| |
| return m_attrSet == *theRHS; |
| } |
| |
| private: |
| |
| const ElemAttributeSet& m_attrSet; |
| }; |
| |
| |
| |
| void |
| Stylesheet::postConstruction(StylesheetConstructionContext& constructionContext) |
| { |
| { |
| m_importsSize = m_imports.size(); |
| |
| // Call postConstruction() on any imported stylesheets, the get any aliases |
| // in reverse order, to preserve import precedence. Also, get any key declarations. |
| const StylesheetVectorType::reverse_iterator theEnd = m_imports.rend(); |
| StylesheetVectorType::reverse_iterator i = m_imports.rbegin(); |
| |
| while(i != theEnd) |
| { |
| (*i)->postConstruction(constructionContext); |
| |
| m_namespacesHandler.copyNamespaceAliases((*i)->getNamespacesHandler()); |
| |
| // $$ ToDo: Should we clear the imported stylesheet's key |
| // declarations after we copy them? |
| m_keyDeclarations.insert( |
| m_keyDeclarations.end(), |
| (*i)->m_keyDeclarations.begin(), |
| (*i)->m_keyDeclarations.end()); |
| |
| ++i; |
| } |
| } |
| |
| // Call postConstruction() on our own namespaces handler... |
| m_namespacesHandler.postConstruction(); |
| |
| |
| { |
| for (ElemTemplateElement* node = m_firstTemplate; |
| node != 0; |
| node = node->getNextSiblingElem()) |
| { |
| node->postConstruction(constructionContext, m_namespacesHandler); |
| } |
| } |
| |
| { |
| for (ElemVariableVectorType::iterator it = m_topLevelVariables.begin(); |
| it != m_topLevelVariables.end(); |
| ++it) |
| { |
| (*it)->postConstruction(constructionContext, m_namespacesHandler); |
| } |
| } |
| |
| { |
| for (ElemTemplateElement* node = m_wrapperlessTemplate; |
| node != 0; |
| node = node->getNextSiblingElem()) |
| { |
| node->postConstruction(constructionContext, m_namespacesHandler); |
| } |
| } |
| |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::find_if; |
| #endif |
| for (AttributeSetVectorType::size_type i = 0; i < m_attributeSets.size(); ++i) |
| { |
| ElemAttributeSet* const theCurrent = m_attributeSets[i]; |
| |
| assert(theCurrent != 0); |
| |
| for(;;) |
| { |
| // Look for duplicate sets... |
| const AttributeSetVectorType::iterator theResult = |
| find_if( |
| m_attributeSets.begin() + (i + 1), |
| m_attributeSets.end(), |
| attrSetCompare(*theCurrent)); |
| |
| // Did we find it? |
| if(theResult == m_attributeSets.end()) |
| { |
| break; |
| } |
| else |
| { |
| theCurrent->adopt(**theResult); |
| |
| delete *theResult; |
| |
| m_attributeSets.erase(theResult); |
| } |
| } |
| |
| theCurrent->postConstruction(constructionContext, m_namespacesHandler); |
| } |
| |
| // Now that we're done with removing duplicates, cache the size... |
| m_attributeSetsSize = m_attributeSets.size(); |
| } |
| |
| // OK, now we need to add everything template that matches "node()" |
| // to the end of the text, comment, and PI template lists. |
| PatternTableListType::iterator theBegin = m_nodePatternList.begin(); |
| PatternTableListType::iterator theEnd = m_nodePatternList.end(); |
| |
| if (theBegin != theEnd) |
| { |
| m_textPatternList.insert( |
| m_textPatternList.end(), |
| theBegin, |
| theEnd); |
| |
| m_commentPatternList.insert( |
| m_commentPatternList.end(), |
| theBegin, |
| theEnd); |
| |
| m_piPatternList.insert( |
| m_piPatternList.end(), |
| theBegin, |
| theEnd); |
| } |
| |
| m_nodePatternList.insert( |
| theEnd, |
| m_anyPatternList.begin(), |
| m_anyPatternList.end()); |
| |
| theBegin = m_nodePatternList.begin(); |
| theEnd = m_nodePatternList.end(); |
| |
| if (theBegin != theEnd) |
| { |
| PatternTableMapType::iterator i = |
| m_patternTable.begin(); |
| |
| while(i != m_patternTable.end()) |
| { |
| PatternTableListType& theTable = (*i).second; |
| |
| theTable.insert( |
| theTable.end(), |
| theBegin, |
| theEnd); |
| |
| ++i; |
| } |
| } |
| |
| m_patternCount = m_matchPattern2Container.size(); |
| } |
| |
| |
| |
| bool |
| Stylesheet::isAttrOK( |
| const XalanDOMChar* attrName, |
| const AttributeList& /* atts */, |
| int /* which */, |
| StylesheetConstructionContext& constructionContext) const |
| { |
| // Namespace declarations are OK by definition |
| bool attrOK = equals(attrName, DOMServices::s_XMLNamespace) || |
| startsWith(attrName, DOMServices::s_XMLNamespaceWithSeparator); |
| |
| if(!attrOK) |
| { |
| // Others are OK if their prefix has been |
| // bound to a non-null Namespace URI other than XSLT's |
| const unsigned int indexOfNSSep = indexOf(attrName, XalanUnicode::charColon); |
| |
| if(indexOfNSSep < length(attrName)) |
| { |
| const XalanDOMString prefix = substring(attrName, 0, indexOfNSSep); |
| const XalanDOMString* ns = getNamespaceForPrefixFromStack(prefix); |
| |
| attrOK = ns != 0 && !::isEmpty(*ns) && !equals(*ns, constructionContext.getXSLTNamespaceURI()); |
| } |
| else |
| { |
| attrOK = false; |
| } |
| } |
| |
| return attrOK; |
| } |
| |
| |
| |
| const XalanDOMString* |
| Stylesheet::getNamespaceFromStack(const XalanDOMChar* nodeName) const |
| { |
| assert(nodeName != 0); |
| |
| const unsigned int indexOfNSSep = indexOf(nodeName, XalanUnicode::charColon); |
| |
| const XalanDOMString prefix = |
| indexOfNSSep < length(nodeName) ? |
| substring(nodeName, 0, indexOfNSSep) : |
| XalanDOMString(); |
| |
| return getNamespaceForPrefixFromStack(prefix); |
| } |
| |
| |
| |
| bool |
| Stylesheet::getYesOrNo( |
| const XalanDOMChar* aname, |
| const XalanDOMChar* val, |
| StylesheetConstructionContext& constructionContext) const |
| { |
| if(equals(val, Constants::ATTRVAL_YES)) |
| { |
| return true; |
| } |
| else if(equals(val, Constants::ATTRVAL_NO)) |
| { |
| return false; |
| } |
| else |
| { |
| constructionContext.error(XalanDOMString(val) + " is unknown value for " + aname); |
| |
| return false; |
| } |
| } |
| |
| |
| |
| void |
| Stylesheet::addTemplate( |
| ElemTemplate* theTemplate, |
| StylesheetConstructionContext& constructionContext) |
| { |
| assert(theTemplate != 0); |
| |
| unsigned int pos = 0; |
| |
| if(0 == m_firstTemplate) |
| { |
| m_firstTemplate = theTemplate; |
| } |
| else |
| { |
| ElemTemplateElement* next = m_firstTemplate; |
| |
| // Find the last one, then append the new one. |
| while(0 != next) |
| { |
| if(0 == next->getNextSiblingElem()) |
| { |
| next->setNextSiblingElem(theTemplate); |
| theTemplate->setNextSiblingElem(0); // just to play it safe. |
| theTemplate->setPreviousSiblingElem(next); |
| break; |
| } |
| |
| pos++; |
| |
| next = next->getNextSiblingElem(); |
| } |
| } |
| |
| // If it's a named template, then we need to |
| // and it to the map of named templates. |
| const XalanQName& theName = theTemplate->getName(); |
| |
| if(theName.isEmpty() == false) |
| { |
| if (m_namedTemplates.find(theName) == m_namedTemplates.end()) |
| { |
| m_namedTemplates[theName] = theTemplate; |
| } |
| else |
| { |
| // This is an error... |
| XalanDOMString theMessage(TranscodeFromLocalCodePage("The stylesheet already has a template with the name ")); |
| |
| const XalanDOMString& theNamespace = theName.getNamespace(); |
| |
| if (length(theNamespace) != 0) |
| { |
| theMessage += theNamespace; |
| theMessage += DOMServices::s_XMLNamespaceSeparatorString; |
| } |
| |
| theMessage += theName.getLocalPart(); |
| |
| constructionContext.error(theMessage, 0, theTemplate); |
| } |
| } |
| |
| // Now, process the match pattern associated with the |
| // template. |
| const XPath* const xp = theTemplate->getMatchPattern(); |
| |
| if(0 != xp) |
| { |
| /* Each string has a list of pattern tables associated with it; if the |
| * string is not in the map, then create a list of pattern tables with one |
| * entry for the string, otherwise add to the existing pattern table list |
| * for that string |
| */ |
| typedef XPath::TargetElementStringsVectorType TargetElementStringsVectorType; |
| |
| TargetElementStringsVectorType strings; |
| |
| xp->getTargetElementStrings(strings); |
| |
| TargetElementStringsVectorType::size_type nTargets = |
| strings.size(); |
| |
| if(nTargets != 0) |
| { |
| for(TargetElementStringsVectorType::size_type stringIndex = 0; |
| stringIndex < nTargets; stringIndex++) |
| { |
| const XalanDOMString& target = strings[stringIndex]; |
| |
| m_matchPattern2Container.push_back( |
| MatchPattern2( |
| *theTemplate, |
| pos, |
| target, |
| *xp, |
| xp->getExpression().getCurrentPattern())); |
| |
| const MatchPattern2* const newMatchPat = |
| &m_matchPattern2Container.back(); |
| |
| // Always put things on the front of the list, so |
| // templates later in the stylesheet are always |
| // selected first. |
| if (equals(target, XPath::PSEUDONAME_TEXT) == true) |
| { |
| m_textPatternList.insert( |
| m_textPatternList.begin(), |
| newMatchPat); |
| } |
| else if (equals(target, XPath::PSEUDONAME_COMMENT) == true) |
| { |
| m_commentPatternList.insert( |
| m_commentPatternList.begin(), |
| newMatchPat); |
| } |
| else if (equals(target, XPath::PSEUDONAME_ROOT) == true) |
| { |
| m_rootPatternList.insert( |
| m_rootPatternList.begin(), |
| newMatchPat); |
| } |
| else if (equals(target, XPath::PSEUDONAME_PI) == true) |
| { |
| m_piPatternList.insert( |
| m_piPatternList.begin(), |
| newMatchPat); |
| } |
| else if (equals(target, XPath::PSEUDONAME_NODE) == true) |
| { |
| m_nodePatternList.insert( |
| m_nodePatternList.begin(), |
| newMatchPat); |
| } |
| else if (equals(target, XPath::PSEUDONAME_ANY) == true) |
| { |
| m_anyPatternList.insert( |
| m_anyPatternList.begin(), |
| newMatchPat); |
| } |
| else |
| { |
| // Put it in the map. |
| PatternTableListType& theTable = |
| m_patternTable[target]; |
| |
| theTable.insert( |
| theTable.begin(), |
| newMatchPat); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| |
| const ElemTemplate* |
| Stylesheet::findNamedTemplate(const XalanQName& qname) const |
| { |
| ElemTemplateMapType::const_iterator it = m_namedTemplates.find(qname); |
| |
| if(it != m_namedTemplates.end()) |
| { |
| return (*it).second; |
| } |
| else |
| { |
| const ElemTemplate* namedTemplate = 0; |
| |
| // Look for the template in the imports |
| const StylesheetVectorType::size_type nImports = m_imports.size(); |
| |
| for(StylesheetVectorType::size_type i = 0; i < nImports; ++i) |
| { |
| const Stylesheet* const stylesheet = m_imports[i]; |
| |
| namedTemplate = stylesheet->findNamedTemplate(qname); |
| |
| if(0 != namedTemplate) |
| break; |
| } |
| |
| return namedTemplate; |
| } |
| } |
| |
| |
| |
| void |
| Stylesheet::addObjectIfNotFound( |
| const MatchPattern2* thePattern, |
| PatternTableVectorType& theVector) |
| { |
| #if !defined(XALAN_NO_NAMESPACES) |
| using std::find; |
| #endif |
| |
| const PatternTableVectorType::const_iterator theResult = |
| find( |
| theVector.begin(), |
| theVector.end(), |
| thePattern); |
| |
| // Did we find it? |
| if(theResult == theVector.end()) |
| { |
| theVector.push_back(thePattern); |
| } |
| } |
| |
| |
| |
| inline void |
| Stylesheet::addObjectIfNotFound( |
| const MatchPattern2* thePattern, |
| const MatchPattern2* thePatternArray[], |
| unsigned int& thePatternArraySize) |
| { |
| if (thePatternArraySize == 0) |
| { |
| thePatternArray[0] = thePattern; |
| |
| ++thePatternArraySize; |
| } |
| else |
| { |
| unsigned int i = 0; |
| |
| while(i < thePatternArraySize) |
| { |
| if (thePatternArray[i] != thePattern) |
| { |
| ++i; |
| } |
| else |
| { |
| break; |
| } |
| } |
| |
| if (i == thePatternArraySize) |
| { |
| thePatternArray[thePatternArraySize++] = thePattern; |
| } |
| } |
| } |
| |
| |
| |
| inline const Stylesheet::PatternTableListType* |
| Stylesheet::locateMatchPatternList2(const XalanDOMString& theName) const |
| { |
| assert(m_patternTableEnd == m_patternTable.end()); |
| |
| const PatternTableMapType::const_iterator i = |
| m_patternTable.find(theName); |
| |
| if (i != m_patternTableEnd) |
| { |
| return &(*i).second; |
| } |
| else |
| { |
| return &m_nodePatternList; |
| } |
| } |
| |
| |
| |
| inline const Stylesheet::PatternTableListType* |
| Stylesheet::locateMatchPatternList2(const XalanNode& theNode) const |
| { |
| switch(theNode.getNodeType()) |
| { |
| case XalanNode::ELEMENT_NODE: |
| return locateMatchPatternList2(DOMServices::getLocalNameOfNode(theNode)); |
| break; |
| |
| case XalanNode::PROCESSING_INSTRUCTION_NODE: |
| return &m_piPatternList; |
| break; |
| |
| case XalanNode::ATTRIBUTE_NODE: |
| return locateMatchPatternList2(DOMServices::getLocalNameOfNode(theNode)); |
| break; |
| |
| case XalanNode::CDATA_SECTION_NODE: |
| case XalanNode::TEXT_NODE: |
| return &m_textPatternList; |
| break; |
| |
| case XalanNode::COMMENT_NODE: |
| return &m_commentPatternList; |
| break; |
| |
| case XalanNode::DOCUMENT_NODE: |
| return &m_rootPatternList; |
| break; |
| |
| case XalanNode::DOCUMENT_FRAGMENT_NODE: |
| return &m_anyPatternList; |
| break; |
| } |
| |
| return locateMatchPatternList2(theNode.getNodeName()); |
| } |
| |
| |
| |
| const ElemTemplate* |
| Stylesheet::findTemplate( |
| StylesheetExecutionContext& executionContext, |
| XalanNode* targetNode, |
| const XalanQName& mode, |
| bool onlyUseImports) const |
| { |
| assert(targetNode != 0); |
| assert(m_patternCount == m_matchPattern2Container.size()); |
| |
| if(m_isWrapperless == true) |
| { |
| return m_wrapperlessTemplate; |
| } |
| else |
| { |
| const ElemTemplate* bestMatchedRule = 0; |
| const MatchPattern2* bestMatchedPattern = 0; // Syncs with bestMatchedRule |
| const double matchScoreNoneValue = |
| XPath::getMatchScoreValue(XPath::eMatchScoreNone); |
| |
| double bestMatchPatPriority = matchScoreNoneValue; |
| |
| |
| unsigned int nConflicts = 0; |
| |
| // Use a stack-based array when possible... |
| const MatchPattern2* conflictsArray[100]; |
| |
| XalanArrayAutoPtr<const MatchPattern2*> conflictsVector; |
| |
| const MatchPattern2** conflicts = 0; |
| |
| if(onlyUseImports == false) |
| { |
| // Points to the current list of match patterns. Note |
| // that this may point to more than one table. |
| const PatternTableListType* matchPatternList = |
| locateMatchPatternList2(*targetNode); |
| assert(matchPatternList != 0); |
| |
| PatternTableListType::const_iterator theCurrentEntry = |
| matchPatternList->begin(); |
| |
| const PatternTableListType::const_iterator theTableEnd = |
| matchPatternList->end(); |
| |
| if (theCurrentEntry != theTableEnd) |
| { |
| const XalanDOMString* prevPat = 0; |
| const MatchPattern2* prevMatchPat = 0; |
| double prevMatchPatPriority = matchScoreNoneValue; |
| |
| do |
| { |
| const MatchPattern2* matchPat = *theCurrentEntry; |
| double matchPatPriority = matchScoreNoneValue; |
| assert(matchPat != 0); |
| |
| const ElemTemplate* const rule = matchPat->getTemplate(); |
| assert(rule != 0); |
| |
| // We'll be needing to match rules according to what |
| // mode we're in. |
| const XalanQName& ruleMode = rule->getMode(); |
| |
| // The logic here should be that if we are not in a mode AND |
| // the rule does not have a node, then go ahead. |
| // OR if we are in a mode, AND the rule has a node, |
| // AND the rules match, then go ahead. |
| const bool haveMode = !mode.isEmpty(); |
| const bool haveRuleMode = !ruleMode.isEmpty(); |
| |
| if ((!haveMode && !haveRuleMode) || |
| (haveMode && haveRuleMode && ruleMode.equals(mode))) |
| { |
| const XalanDOMString* patterns = matchPat->getPattern(); |
| assert(patterns != 0); |
| |
| if(!isEmpty(*patterns) && |
| !(prevMatchPat != 0 && |
| (prevPat != 0 && equals(*prevPat, *patterns)) && |
| prevMatchPat->getTemplate()->getPriority() == matchPat->getTemplate()->getPriority())) |
| { |
| prevPat = patterns; |
| prevMatchPat = matchPat; |
| prevMatchPatPriority = matchPatPriority; |
| matchPatPriority = matchScoreNoneValue; |
| |
| const XPath* const xpath = matchPat->getExpression(); |
| |
| XPath::eMatchScore score = |
| xpath->getMatchScore(targetNode, *this, executionContext); |
| |
| if(XPath::eMatchScoreNone != score) |
| { |
| const double priorityVal = rule->getPriority(); |
| const double priorityOfRule |
| = (matchScoreNoneValue != priorityVal) |
| ? priorityVal : XPath::getMatchScoreValue(score); |
| |
| matchPatPriority = priorityOfRule; |
| const double priorityOfBestMatched = |
| (0 != bestMatchedPattern) ? |
| bestMatchPatPriority : |
| matchScoreNoneValue; |
| |
| if(priorityOfRule > priorityOfBestMatched) |
| { |
| nConflicts = 0; |
| |
| bestMatchedRule = rule; |
| bestMatchedPattern = matchPat; |
| bestMatchPatPriority = matchPatPriority; |
| } |
| else if(priorityOfRule == priorityOfBestMatched) |
| { |
| if (conflicts == 0) |
| { |
| if (m_patternCount > sizeof(conflictsArray) / sizeof(conflictsArray[0])) |
| { |
| conflictsVector.reset(new const MatchPattern2*[m_patternCount]); |
| |
| conflicts = conflictsVector.get(); |
| } |
| else |
| { |
| conflicts = conflictsArray; |
| } |
| } |
| |
| assert(conflicts != 0); |
| |
| // Add the best matched pattern so far. |
| addObjectIfNotFound(bestMatchedPattern, conflicts, nConflicts); |
| |
| // Add the pattern that caused the conflict... |
| conflicts[nConflicts++] = matchPat; |
| |
| bestMatchedRule = rule; |
| bestMatchedPattern = matchPat; |
| bestMatchPatPriority = matchPatPriority; |
| } |
| } |
| } |
| } |
| |
| ++theCurrentEntry; |
| |
| } while(theCurrentEntry != theTableEnd); |
| } |
| } // end if(useImports == false) |
| |
| if(0 == bestMatchedRule) |
| { |
| assert(m_importsSize == m_imports.size()); |
| |
| for(unsigned int i = 0; i < m_importsSize; i++) |
| { |
| const Stylesheet* const stylesheet = |
| m_imports[i]; |
| |
| bestMatchedRule = stylesheet->findTemplate(executionContext, |
| targetNode, |
| mode, |
| false); |
| if(0 != bestMatchedRule) |
| break; |
| } |
| } |
| |
| if(nConflicts > 0) |
| { |
| assert(conflicts != 0); |
| |
| const bool quietConflictWarnings = executionContext.getQuietConflictWarnings(); |
| |
| XalanDOMString conflictsString; |
| |
| if (quietConflictWarnings == false) |
| { |
| conflictsString = XALAN_STATIC_UCODE_STRING("Specificity conflicts found: "); |
| } |
| |
| for(unsigned int i = 0; i < nConflicts; i++) |
| { |
| const MatchPattern2* const conflictPat = conflicts[i]; |
| |
| if(0 != i) |
| { |
| if(quietConflictWarnings == false) |
| { |
| conflictsString += XALAN_STATIC_UCODE_STRING(", "); |
| } |
| // Find the furthest one towards the bottom of the document. |
| if(conflictPat->getPositionInStylesheet() > |
| bestMatchedPattern->getPositionInStylesheet()) |
| { |
| bestMatchedPattern = conflictPat; |
| } |
| } |
| else |
| { |
| bestMatchedPattern = conflictPat; |
| } |
| |
| if(quietConflictWarnings == false) |
| { |
| conflictsString += XalanDOMString(XALAN_STATIC_UCODE_STRING("\"")) + |
| *conflictPat->getPattern() + |
| XalanDOMString(XALAN_STATIC_UCODE_STRING("\"")); |
| } |
| } |
| |
| bestMatchedRule = bestMatchedPattern->getTemplate(); |
| |
| if(quietConflictWarnings == false) |
| { |
| conflictsString += XALAN_STATIC_UCODE_STRING(" "); |
| conflictsString += XALAN_STATIC_UCODE_STRING("Last found in stylesheet will be used."); |
| executionContext.warn(conflictsString); |
| } |
| } |
| |
| return bestMatchedRule; |
| } |
| } |
| |
| |
| |
| void |
| Stylesheet::addExtensionNamespace( |
| const XalanDOMString& uri, |
| ExtensionNSHandler* nsh) |
| { |
| m_extensionNamespaces.insert(ExtensionNamespacesMapType::value_type(uri, nsh)); |
| |
| m_namespacesHandler.addExtensionNamespaceURI(uri); |
| } |
| |
| |
| |
| void |
| Stylesheet::pushTopLevelVariables( |
| StylesheetExecutionContext& executionContext, |
| const ParamVectorType& topLevelParams) const |
| { |
| { |
| // First, push any imports... |
| const StylesheetVectorType::const_reverse_iterator rend = m_imports.rend(); |
| |
| for(StylesheetVectorType::const_reverse_iterator i = m_imports.rbegin(); i != rend; ++i) |
| { |
| const Stylesheet* const stylesheet = *i; |
| assert(stylesheet != 0); |
| |
| stylesheet->pushTopLevelVariables(executionContext, topLevelParams); |
| } |
| } |
| |
| const ParamVectorType::size_type nVars = m_topLevelVariables.size(); |
| |
| for(ParamVectorType::size_type i = 0; i < nVars; ++i) |
| { |
| ElemVariable* const var = m_topLevelVariables[i]; |
| |
| bool isParam = |
| Constants::ELEMNAME_PARAMVARIABLE == var->getXSLToken(); |
| |
| if(isParam == true) |
| { |
| isParam = false; |
| |
| const ParamVectorType::size_type n = topLevelParams.size(); |
| |
| for(ParamVectorType::size_type k = 0; k < n; k++) |
| { |
| const ParamVectorType::value_type& arg = topLevelParams[k]; |
| |
| if(arg.getName().equals(var->getName())) |
| { |
| isParam = true; |
| |
| if (arg.getXObject().null() == false) |
| { |
| executionContext.pushVariable( |
| arg.getName(), |
| arg.getXObject(), |
| 0); |
| } |
| else |
| { |
| executionContext.pushVariable( |
| arg.getName(), |
| 0, |
| arg.getExpression(), |
| executionContext.getRootDocument(), |
| *this); |
| } |
| |
| break; |
| } |
| } |
| } |
| |
| if (isParam == false) |
| { |
| executionContext.pushVariable(var->getName(), |
| var, |
| var->getParentNodeElem()); |
| } |
| } |
| } |
| |
| |
| |
| void |
| Stylesheet::processNSAliasElement( |
| const XalanDOMChar* name, |
| const AttributeList& atts, |
| StylesheetConstructionContext& constructionContext) |
| { |
| const unsigned int nAttrs = atts.getLength(); |
| |
| const XalanDOMString* stylesheetNamespace = &DOMServices::s_emptyString; |
| const XalanDOMString* resultNamespace = &DOMServices::s_emptyString; |
| const XalanDOMString dummy; |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if(equals(aname, Constants::ATTRNAME_STYLESHEET_PREFIX) == true) |
| { |
| const XalanDOMChar* const value = atts.getValue(i); |
| |
| if (equals(value, Constants::ATTRVAL_DEFAULT_PREFIX) == true) |
| { |
| stylesheetNamespace = getNamespaceForPrefix(dummy); |
| } |
| else |
| { |
| stylesheetNamespace = getNamespaceForPrefix(XalanDOMString(value)); |
| } |
| } |
| else if(equals(aname, Constants::ATTRNAME_RESULT_PREFIX)) |
| { |
| const XalanDOMChar* const value = atts.getValue(i); |
| |
| if (equals(value, Constants::ATTRVAL_DEFAULT_PREFIX) == true) |
| { |
| resultNamespace = getNamespaceForPrefix(dummy); |
| } |
| else |
| { |
| resultNamespace = getNamespaceForPrefix(XalanDOMString(value)); |
| } |
| } |
| else if(!isAttrOK(aname, atts, i, constructionContext)) |
| { |
| constructionContext.error(XalanDOMString(name) + " has an illegal attribute: " + aname); |
| } |
| } |
| |
| // Build a table of aliases, the key is the stylesheet uri and the |
| // value is the result uri |
| if (length(*stylesheetNamespace) == 0 || |
| length(*resultNamespace) == 0) |
| { |
| constructionContext.error("Missing namespace URI for specified prefix"); |
| } |
| else |
| { |
| #if 1 |
| // $$$ ToDo: Enable other code. Perhaps an error? |
| m_prefixAliases[*stylesheetNamespace] = *resultNamespace; |
| |
| m_namespacesHandler.setNamespaceAlias(*stylesheetNamespace, *resultNamespace); |
| #else |
| const PrefixAliasesMapType::iterator i = |
| m_prefixAliases.find(*stylesheetNamespace); |
| |
| if (i != m_prefixAliases.end()) |
| { |
| // $$$ ToDo: This could also be an error? |
| (*i).second = *resultNamespace; |
| } |
| else |
| { |
| m_prefixAliases.insert(PrefixAliasesMapType::value_type(*stylesheetNamespace, *resultNamespace)); |
| } |
| #endif |
| } |
| } |
| |
| |
| |
| XalanDOMString |
| Stylesheet::getAliasNamespaceURI(const XalanDOMChar* uri) const |
| { |
| assert(uri != 0); |
| |
| return getAliasNamespaceURI(XalanDOMString(uri)); |
| } |
| |
| |
| |
| XalanDOMString |
| Stylesheet::getAliasNamespaceURI(const XalanDOMString& uri) const |
| { |
| const StringToStringMapType::const_iterator i = |
| m_prefixAliases.find(uri); |
| |
| if (i != m_prefixAliases.end()) |
| { |
| assert(length((*i).second) > 0); |
| |
| return (*i).second; |
| } |
| else |
| { |
| XalanDOMString theResult; |
| |
| const StylesheetVectorType::size_type nImports = |
| m_imports.size(); |
| |
| for(StylesheetVectorType::size_type i = 0; i < nImports; ++i) |
| { |
| theResult = m_imports[i]->getAliasNamespaceURI(uri); |
| |
| if(length(theResult) != 0) |
| { |
| break; |
| } |
| } |
| |
| return theResult; |
| } |
| } |
| |
| |
| |
| const XalanDecimalFormatSymbols* |
| Stylesheet::getDecimalFormatSymbols(const XalanDOMString& name) const |
| { |
| const XalanDecimalFormatSymbols* dfs = 0; |
| |
| const ElemDecimalFormatVectorType::size_type theSize = |
| m_elemDecimalFormats.size(); |
| |
| if(theSize > 0) |
| { |
| // Start from the top of the stack |
| for (int i = theSize - 1; i >= 0; --i) |
| { |
| assert(m_elemDecimalFormats[i] != 0); |
| |
| if (equals(m_elemDecimalFormats[i]->getName(), name) == true) |
| { |
| dfs = &m_elemDecimalFormats[i]->getDecimalFormatSymbols(); |
| |
| break; |
| } |
| } |
| } |
| |
| // If dfs is null at this point, it should |
| // mean there wasn't an xsl:decimal-format declared |
| // with the given name. So go up the import hierarchy |
| // and see if one of the imported stylesheets declared |
| // it. |
| if(dfs == 0) |
| { |
| for(StylesheetVectorType::size_type i = 0; i < m_importsSize; ++i) |
| { |
| dfs = m_imports[i]->getDecimalFormatSymbols(name); |
| |
| if(dfs != 0) |
| { |
| break; |
| } |
| } |
| } |
| |
| return dfs; |
| } |
| |
| |
| |
| void |
| Stylesheet::applyAttrSets( |
| const QNameVectorType& attributeSetsNames, |
| StylesheetExecutionContext& executionContext, |
| XalanNode* sourceNode) const |
| { |
| const QNameVectorType::size_type nNames = attributeSetsNames.size(); |
| |
| if(0 != nNames) |
| { |
| assert(m_importsSize == m_imports.size()); |
| |
| // Process up the import chain... |
| for(StylesheetVectorType::size_type i = 0; i < m_importsSize; i++) |
| { |
| const Stylesheet* const stylesheet = m_imports[i]; |
| |
| stylesheet->applyAttrSets( |
| attributeSetsNames, |
| executionContext, |
| sourceNode); |
| } |
| |
| for(QNameVectorType::size_type j = 0; j < nNames; j++) |
| { |
| const XalanQName& qname = attributeSetsNames[j]; |
| |
| assert(m_attributeSetsSize == m_attributeSets.size()); |
| |
| for(StylesheetVectorType::size_type k = 0; k < m_attributeSetsSize; k++) |
| { |
| const ElemAttributeSet* const attrSet = m_attributeSets[k]; |
| assert(attrSet != 0); |
| |
| if(qname.equals(attrSet->getQName())) |
| { |
| attrSet->execute(executionContext); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getNodeName() const |
| { |
| return s_emptyString; |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getNodeValue() const |
| { |
| return s_emptyString; |
| } |
| |
| |
| |
| Stylesheet::NodeType |
| Stylesheet::getNodeType() const |
| { |
| return XalanNode::DOCUMENT_NODE; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::getParentNode() const |
| { |
| return 0; |
| } |
| |
| |
| |
| const XalanNodeList* |
| Stylesheet::getChildNodes() const |
| { |
| return &m_surrogateChildren; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::getFirstChild() const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::getLastChild() const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::getPreviousSibling() const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::getNextSibling() const |
| { |
| return 0; |
| } |
| |
| |
| |
| const XalanNamedNodeMap* |
| Stylesheet::getAttributes() const |
| { |
| return &s_fakeAttributes; |
| } |
| |
| |
| |
| XalanDocument* |
| Stylesheet::getOwnerDocument() const |
| { |
| return 0; |
| } |
| |
| |
| |
| #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) |
| XalanNode* |
| #else |
| Stylesheet* |
| #endif |
| Stylesheet::cloneNode(bool /* deep */) const |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::insertBefore( |
| XalanNode* /* newChild */, |
| XalanNode* /* refChild */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::replaceChild( |
| XalanNode* /* newChild */, |
| XalanNode* /* oldChild */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::removeChild(XalanNode* /* oldChild */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::appendChild(XalanNode* /* oldChild */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| bool |
| Stylesheet::hasChildNodes() const |
| { |
| // $$$ ToDo: Is this always true? |
| return true; |
| } |
| |
| |
| |
| void |
| Stylesheet::setNodeValue(const XalanDOMString& /* nodeValue */) |
| { |
| throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR); |
| } |
| |
| |
| |
| void |
| Stylesheet::normalize() |
| { |
| } |
| |
| |
| |
| bool |
| Stylesheet::supports( |
| const XalanDOMString& /* feature */, |
| const XalanDOMString& /* version */) const |
| { |
| return false; |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getNamespaceURI() const |
| { |
| // $$ ToDo: Is this the same value as PrefixResolver::getURI()? |
| return s_emptyString; |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getPrefix() const |
| { |
| return s_emptyString; |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getLocalName() const |
| { |
| return s_emptyString; |
| } |
| |
| |
| |
| void |
| Stylesheet::setPrefix(const XalanDOMString& /* prefix */) |
| { |
| throw XalanDOMException(XalanDOMException::NO_MODIFICATION_ALLOWED_ERR); |
| } |
| |
| |
| |
| unsigned long |
| Stylesheet::getIndex() const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanElement* |
| Stylesheet::createElement(const XalanDOMString& /* tagName */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanDocumentFragment* |
| Stylesheet::createDocumentFragment() |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanText* |
| Stylesheet::createTextNode(const XalanDOMString& /* data */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanComment* |
| Stylesheet::createComment(const XalanDOMString& /* data */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanCDATASection* |
| Stylesheet::createCDATASection(const XalanDOMString& /* data */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanProcessingInstruction* |
| Stylesheet::createProcessingInstruction( |
| const XalanDOMString& /* target */, |
| const XalanDOMString& /* data */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanAttr* |
| Stylesheet::createAttribute(const XalanDOMString& /* name */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanEntityReference* |
| Stylesheet::createEntityReference(const XalanDOMString& /* name */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanDocumentType* |
| Stylesheet::getDoctype() const |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanDOMImplementation* |
| Stylesheet::getImplementation() const |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanElement* |
| Stylesheet::getDocumentElement() const |
| { |
| // $$$ ToDo: Is this correct? |
| |
| return m_wrapperlessTemplate != 0 ? m_wrapperlessTemplate : m_firstTemplate; |
| } |
| |
| |
| |
| XalanNodeList* |
| Stylesheet::getElementsByTagName(const XalanDOMString& /* name */) const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanNodeList* |
| Stylesheet::getElementsByTagNameNS( |
| const XalanDOMString& /* namespaceURI */, |
| const XalanDOMString& /* localName */) const |
| { |
| return 0; |
| } |
| |
| |
| |
| XalanNode* |
| Stylesheet::importNode( |
| XalanNode* /* importedNode */, |
| bool /* deep */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanElement* |
| Stylesheet::createElementNS( |
| const XalanDOMString& /* namespaceURI */, |
| const XalanDOMString& /* qualifiedName */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanAttr* |
| Stylesheet::createAttributeNS( |
| const XalanDOMString& /* namespaceURI */, |
| const XalanDOMString& /* qualifiedName */) |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| XalanElement* |
| Stylesheet::getElementById(const XalanDOMString& /* elementId */) const |
| { |
| //should not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| bool |
| Stylesheet::isIndexed() const |
| { |
| // This member functionshould not be called |
| assert(false); |
| |
| return false; |
| } |
| |
| |
| |
| unsigned long |
| Stylesheet::getNumber() const |
| { |
| // This member functionshould not be called |
| assert(false); |
| |
| return 0; |
| } |
| |
| |
| |
| const XalanDOMString* |
| Stylesheet::getNamespaceForPrefix(const XalanDOMString& prefix) const |
| { |
| return XalanQName::getNamespaceForPrefix(m_namespaceDecls, prefix); |
| } |
| |
| |
| |
| const XalanDOMString& |
| Stylesheet::getURI() const |
| { |
| return m_baseIdent; |
| } |