Logo Search packages:      
Sourcecode: xalan version File versions  Download package

void StylesheetHandler::startElement ( const XMLCh *const   name,
AttributeListType &  attrs 
) [virtual]

Receive notification of the beginning of an element.

The Parser will invoke this method at the beginning of every element in the XML document; there will be a corresponding endElement() event for every startElement() event (even when the element is empty). All of the element's content will be reported, in order, before the corresponding endElement() event.

If the element name has a namespace prefix, the prefix will still be attached. Note that the attribute list provided will contain only attributes with explicit values (specified or defaulted): IMPLIED attributes will be omitted.

Parameters:
name element type name
atts attributes attached to the element, if any
Exceptions:
SAXException 
See also:
endElement

org.xml.sax.AttributeList

Definition at line 227 of file StylesheetHandler.cpp.

References Stylesheet::getXSLTNamespaceURI(), Stylesheet::getXSLTVerDeclared(), initWrapperless(), Stylesheet::lookupExtensionNSHandler(), m_constructionContext, m_elemEmptyAllocator, m_elemStack, m_elemTextAllocator, m_foundStylesheet, m_inTemplate, m_stylesheet, m_whiteSpaceElems, processSpaceAttr(), Stylesheet::pushNamespaces(), and Stylesheet::setXSLTNamespaceURI().

{
    m_inExtensionElementStack.push_back(false);

    if (m_preserveSpaceStack.empty() == true)
    {
        m_preserveSpaceStack.push_back(false);
    }
    else
    {
        m_preserveSpaceStack.push_back(m_preserveSpaceStack.back());
    }

    try
    {
        // By default, space is not preserved...
        bool    fPreserveSpace = false;
        bool    fSpaceAttrProcessed = false;

        processAccumulatedText();

        m_whiteSpaceElems.clear();

        const LocatorType* const    locator = m_constructionContext.getLocatorFromStack();

        // First push namespaces
        m_stylesheet.pushNamespaces(atts);

        const XalanDOMString::size_type     nameLength = length(name);
        const XalanDOMString::size_type     index = indexOf(name, XalanUnicode::charColon);

        const GetAndReleaseCachedString     theGuard2(m_constructionContext);
        XalanDOMString&     buffer = theGuard2.get();

        const XalanDOMString*   ns = getNamespaceFromStack(name, buffer);

        if(ns == 0)
        {
            if (index < nameLength)
            {
                const GetAndReleaseCachedString     theGuard(m_constructionContext);

                error(
                    XalanMessageLoader::getMessage(
                        theGuard.get(),
                        XalanMessages::PrefixIsNotDeclared_1Param,
                        name),
                    locator);
            }
            else
            {
                ns = &s_emptyString;
            }
        }
        assert(ns != 0);

        if (index < nameLength)
        {
            m_elementLocalName.assign(name + index + 1, nameLength - index - 1);
        }
        else
        {
            m_elementLocalName.assign(name, nameLength);
        }

        ElemTemplateElement* elem = 0;

        const ElemTemplateStackType::size_type  origStackSize = m_elemStack.size();

        if(equals(*ns, m_constructionContext.getXSLTNamespaceURI()))
        {
            if(!isEmpty(m_stylesheet.getXSLTNamespaceURI()))
                m_stylesheet.setXSLTNamespaceURI(*ns);

            const StylesheetConstructionContext::eElementToken  xslToken =
                m_constructionContext.getElementToken(m_elementLocalName);

            if(!m_inTemplate)
            {
                processTopLevelElement(name, atts, xslToken, locator, fPreserveSpace, fSpaceAttrProcessed);
            }
            else
            {
                switch(xslToken)
                {            
                case StylesheetConstructionContext::ELEMNAME_APPLY_TEMPLATES:
                case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE:
                case StylesheetConstructionContext::ELEMNAME_CALL_TEMPLATE:
                case StylesheetConstructionContext::ELEMNAME_CHOOSE:
                case StylesheetConstructionContext::ELEMNAME_COMMENT:
                case StylesheetConstructionContext::ELEMNAME_COPY:
                case StylesheetConstructionContext::ELEMNAME_COPY_OF:
                case StylesheetConstructionContext::ELEMNAME_ELEMENT:
                case StylesheetConstructionContext::ELEMNAME_FALLBACK:
                case StylesheetConstructionContext::ELEMNAME_FOR_EACH:
                case StylesheetConstructionContext::ELEMNAME_IF:
                case StylesheetConstructionContext::ELEMNAME_MESSAGE:
                case StylesheetConstructionContext::ELEMNAME_NUMBER:
                case StylesheetConstructionContext::ELEMNAME_VALUE_OF:
                case StylesheetConstructionContext::ELEMNAME_WITH_PARAM:
                case StylesheetConstructionContext::ELEMNAME_PI:
                    elem = m_constructionContext.createElement(
                                                xslToken,
                                                m_stylesheet,
                                                atts,
                                                locator);
                    assert(elem != 0);
                    break;
          
                case StylesheetConstructionContext::ELEMNAME_PARAM:
                    elem = m_constructionContext.createElement(
                                                xslToken,
                                                m_stylesheet,
                                                atts,
                                                locator);

                    checkForOrAddVariableName(elem->getNameAttribute(), locator);

                    assert(elem != 0);
                    break;

                case StylesheetConstructionContext::ELEMNAME_SORT:
                    {
                        if (m_elemStack.empty() == true)
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::IsNotAllowedInThisPosition_1Param,
                                    Constants::ELEMNAME_SORT_WITH_PREFIX_STRING),
                                locator);
                        }

                        ElemTemplateElement* const  theElement =
                                m_elemStack.back();
                        assert(theElement != 0);

                        theElement->processSortElement(
                            m_constructionContext,
                            m_stylesheet,
                            atts,
                            locator);

                        m_elemStack.push_back(
                            m_elemEmptyAllocator.create(
                                    m_constructionContext,
                                    m_stylesheet,
                                    &Constants::ELEMNAME_SORT_WITH_PREFIX_STRING));
                    }
                    break;

                case StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS:
                    {
                        if (m_elemStack.empty() == true)
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::IsNotAllowedInThisPosition_1Param,
                                    Constants::ELEMNAME_APPLY_IMPORTS_WITH_PREFIX_STRING),
                                locator);
                        }

                        ElemTemplateElement* const  theElement =
                                m_elemStack.back();
                        assert(theElement != 0);

                        const int   parentToken =
                            theElement->getXSLToken();

                        if (parentToken == StylesheetConstructionContext::ELEMNAME_FOR_EACH)
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::IsNotAllowedInThisPosition_1Param,
                                    Constants::ELEMNAME_APPLY_IMPORTS_WITH_PREFIX_STRING),
                                locator);
                        }

                        elem = m_constructionContext.createElement(
                                                    xslToken,
                                                    m_stylesheet,
                                                    atts,
                                                    locator);
                        assert(elem != 0);
                    }
                    break;
          
                case StylesheetConstructionContext::ELEMNAME_VARIABLE:
                    {
                        elem =
                            m_constructionContext.createElement(
                                                xslToken,
                                                m_stylesheet,
                                                atts,
                                                locator);
                        assert(elem != 0);

                        checkForOrAddVariableName(elem->getNameAttribute(), locator);
                    }
                    break;

                case StylesheetConstructionContext::ELEMNAME_WHEN:
                    {
                        ElemTemplateElement* const  parent = m_elemStack.back();

                        if(StylesheetConstructionContext::ELEMNAME_CHOOSE != parent->getXSLToken())
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::NotParentedBy_2Param,
                                    Constants::ELEMNAME_WHEN_WITH_PREFIX_STRING,
                                    Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING),
                                locator);
                        }
                        else
                        {
                            ElemTemplateElement* const  lastChild = parent->getLastChildElem();

                            if(0 == lastChild ||
                                StylesheetConstructionContext::ELEMNAME_WHEN == lastChild->getXSLToken() ||
                                lastChild->isWhitespace() == true)
                            {
                                elem = m_constructionContext.createElement(
                                                            xslToken,
                                                            m_stylesheet,
                                                            atts,
                                                            locator);
                                assert(elem != 0);
                            }
                            else
                            {
                                const GetAndReleaseCachedString     theGuard(m_constructionContext);

                                error(
                                    XalanMessageLoader::getMessage(
                                        theGuard.get(),
                                        XalanMessages::IsNotAllowedInThisPosition_1Param,
                                        Constants::ELEMNAME_WHEN_WITH_PREFIX_STRING),
                                    locator);
                            }
                        }
                    }
                    break;
          
                case StylesheetConstructionContext::ELEMNAME_OTHERWISE:
                    {
                        ElemTemplateElement* parent = m_elemStack.back();

                        if(StylesheetConstructionContext::ELEMNAME_CHOOSE != parent->getXSLToken())
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::NotParentedBy_2Param,
                                    Constants::ELEMNAME_OTHERWISE_WITH_PREFIX_STRING,
                                    Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING),
                                locator);
                        }
                        else
                        {
                            ElemTemplateElement* lastChild = parent->getLastChildElem();

                            if(0 == lastChild ||
                                StylesheetConstructionContext::ELEMNAME_WHEN == lastChild->getXSLToken() ||
                                lastChild->isWhitespace() == true)
                            {
                                elem = m_constructionContext.createElement(
                                                            xslToken,
                                                            m_stylesheet,
                                                            atts,
                                                            locator);
                                assert(elem != 0);
                            }
                            else
                            {
                                const GetAndReleaseCachedString     theGuard(m_constructionContext);

                                error(
                                    XalanMessageLoader::getMessage(
                                        theGuard.get(),
                                        XalanMessages::IsNotAllowedInThisPosition_1Param,
                                        Constants::ELEMNAME_OTHERWISE_WITH_PREFIX_STRING),
                                    locator);
                            }
                        }
                    }
                    break;

                case StylesheetConstructionContext::ELEMNAME_TEXT:
                    m_elemStack.push_back(
                        m_elemTextAllocator.create(
                            m_constructionContext,
                            m_stylesheet,
                            atts,
                            XalanLocator::getLineNumber(locator),
                            XalanLocator::getColumnNumber(locator)));

                    // This fixes Bugzilla 26354, but it's really a workaround
                    // for the bizarre way we handle literal text in the
                    // stylesheet.  We should examine this strategy, because
                    // an xml:space attribute on an xsl:text element results
                    // in building a stylesheet that tries to parent an
                    // ElenTextLiteral instance to an ElemText instance, which
                    // should not ever happen.
                    fSpaceAttrProcessed = true;
                    break;

                case StylesheetConstructionContext::ELEMNAME_TEMPLATE:
                case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE_SET:
                case StylesheetConstructionContext::ELEMNAME_EXTENSION:
                case StylesheetConstructionContext::ELEMNAME_EXTENSION_HANDLER:
                case StylesheetConstructionContext::ELEMNAME_KEY:
                case StylesheetConstructionContext::ELEMNAME_IMPORT:
                case StylesheetConstructionContext::ELEMNAME_INCLUDE:
                case StylesheetConstructionContext::ELEMNAME_PRESERVE_SPACE:
                case StylesheetConstructionContext::ELEMNAME_STRIP_SPACE:
                case StylesheetConstructionContext::ELEMNAME_DECIMAL_FORMAT:
                    {
                        const GetAndReleaseCachedString     theGuard(m_constructionContext);

                        error(
                            XalanMessageLoader::getMessage(
                                theGuard.get(),
                                XalanMessages::IsNotAllowedInsideTemplate_1Param,
                                name),
                            locator);
                    }
                    break;

                default:
                    {
                        // If this stylesheet is declared to be of a higher version than the one
                        // supported, don't flag an error.
                        if(m_constructionContext.getXSLTVersionSupported() < m_stylesheet.getXSLTVerDeclared())
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            warn(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::UnknownXSLElement_1Param,
                                    name),
                                locator);

                            elem = m_constructionContext.createElement(
                                StylesheetConstructionContext::ELEMNAME_FORWARD_COMPATIBLE,
                                m_stylesheet,
                                name,
                                atts,
                                locator);
                        }
                        else
                        {
                            const GetAndReleaseCachedString     theGuard(m_constructionContext);

                            error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::UnknownXSLElement_1Param,
                                    name),
                                locator);
                        }
                    }
                }

                m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1);
            }
        }
        else if (!m_inTemplate && startsWith(*ns, m_constructionContext.getXalanXSLNameSpaceURL()))
        {
            processExtensionElement(name, m_elementLocalName, atts, locator);
        }
        else
        {
            if(!m_inTemplate)
            {
                // If it's a top level 
                if (!m_foundStylesheet)
                {
                    elem = initWrapperless(name, atts, locator);
                }
                else if (length(*ns) == 0 && m_elemStack.size() == 1)
                {
                    const GetAndReleaseCachedString     theGuard(m_constructionContext);

                    error(
                        XalanMessageLoader::getMessage(
                            theGuard.get(),
                            XalanMessages::IsNotAllowedInThisPosition_1Param,
                            name),
                        locator);
                }
                else
                {
                    m_inExtensionElementStack.back() = true;
                }
            }
            else
            {
                m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1);

                // BEGIN SANJIVA CODE
                // is this an extension element call?
                ExtensionNSHandler*     nsh = 0;

                if (!isEmpty(*ns) &&
                    ((nsh = m_stylesheet.lookupExtensionNSHandler(*ns)) != 0))
                {
                    elem = m_constructionContext.createElement(
                                                m_stylesheet,
                                                name,
                                                atts,
                                                *nsh,
                                                locator);
                    assert(m_inExtensionElementStack.empty() == false);

                    m_inExtensionElementStack.back() = true;
                }
                else 
                {
                    elem = m_constructionContext.createElement(
                                                StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT,
                                                m_stylesheet,
                                                name,
                                                atts,
                                                locator);
                }

                assert(elem != 0);
            }
        }

        if(m_inTemplate && 0 != elem)
        {
            if(!m_elemStack.empty())
            {
                appendChildElementToParent(elem, locator);
            }

            m_elemStack.push_back(elem);
        }

        // If we haven't processed an xml:space attribute already, look for one...
        if (fSpaceAttrProcessed == false)
        {
            fSpaceAttrProcessed = processSpaceAttr(name, atts, locator, fPreserveSpace);
        }

        // Only update the stack if we actually processed an xml:space attribute...
        if (fSpaceAttrProcessed == true)
        {
            // Set the preserve value...
            m_preserveSpaceStack.back() = fPreserveSpace;
        }

        // If for some reason something didn't get pushed, push an empty 
        // object.
        if(origStackSize == m_elemStack.size())
        {
            m_elemStack.push_back(m_elemEmptyAllocator.create(m_constructionContext, m_stylesheet));
        }
    } // end try
    catch(...)
    {
        doCleanup();

        throw;
    }
}


Generated by  Doxygen 1.6.0   Back to index