Ejemplo n.º 1
0
Type*
XalanCopyConstruct(
            MemoryManager&  theMemoryManager,
            const Type&     theSource,
            Param1Type&     theParam1)
{
    XalanAllocationGuard    theGuard(
                                theMemoryManager,
                                sizeof(Type));

    Type* const     theInstance =
        new (theGuard.get()) Type(theSource, theParam1);

    theGuard.release();

    return theInstance;
}
Ejemplo n.º 2
0
Type*
XalanConstruct(
            MemoryManager&      theMemoryManager,
            Type*&              theInstance,
            Param1Type&         theParam1,
            const Param2Type&   theParam2)
{
    XalanAllocationGuard    theGuard(
                                theMemoryManager,
                                sizeof(Type));

    theInstance =
        new (theGuard.get()) Type(theParam1, theParam2);

    theGuard.release();

    return theInstance;
}
Ejemplo n.º 3
0
ExtensionNSHandler*
ExtensionNSHandler::create(
            const XalanDOMString&   namespaceUri,
            MemoryManager&          theManager)
{
    typedef ExtensionNSHandler  ThisType;

    XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

    ThisType* const     theResult =
        new (theGuard.get()) ThisType(
                                namespaceUri,
                                theManager);

    theGuard.release();

    return theResult;
}
void
NamespacesHandler::processExtensionElementPrefixes(
            StylesheetConstructionContext&  theConstructionContext,
            const XalanDOMChar*             theValue,
            const NamespacesStackType&      theCurrentNamespaces)
{
    typedef StylesheetConstructionContext::GetAndReleaseCachedString    GetAndReleaseCachedString;

    StringTokenizer     tokenizer(
                    theValue,
                    Constants::DEFAULT_WHITESPACE_SEPARATOR_STRING);

    const GetAndReleaseCachedString     theGuard(theConstructionContext);

    XalanDOMString&     thePrefix = theGuard.get();

    while(tokenizer.hasMoreTokens() == true)
    {
        tokenizer.nextToken(thePrefix);

        if(equalsIgnoreCaseASCII(thePrefix, Constants::ATTRVAL_DEFAULT_PREFIX) == true)
        {
            thePrefix.clear();
        }

        const XalanDOMString* const     theNamespace =
            XalanQName::getNamespaceForPrefix(theCurrentNamespaces, thePrefix);

        if(theNamespace == 0)
        {
            GetAndReleaseCachedString   theGuard(theConstructionContext);

            theConstructionContext.error(
                XalanMessageLoader::getMessage(
                    theGuard.get(),
                    XalanMessages::PrefixIsNotDeclared_1Param,
                    thePrefix));
        }

        assert(theNamespace != 0);

        m_extensionNamespaceURIs.push_back(&theConstructionContext.getPooledString(*theNamespace));
    }
}
void
NamespacesHandler::createResultAttributeNames(StylesheetConstructionContext&    theConstructionContext)
{
    // Go through all of the result namespaces and create the attribute
    // name that will be used when they're written to the result tree.
    // This is more efficient if the stylesheet is used multiple times.
    if (m_namespaceDeclarations.empty() == false)
    {
        const NamespaceExtendedVectorType::iterator theEnd =
                m_namespaceDeclarations.end();

        NamespaceExtendedVectorType::iterator       i =
                m_namespaceDeclarations.begin();

        StylesheetConstructionContext::GetAndReleaseCachedString theGuard(theConstructionContext);
        XalanDOMString& theName = theGuard.get();

        for(; i != theEnd; ++i)
        {
            NamespaceExtended&      theNamespace = *i;

            const XalanDOMString&   thePrefix = theNamespace.getPrefix();

            if (isEmpty(thePrefix) == false)
            {
                // Create a name of the form xmlns:prefix, where "prefix" is the
                // text of the prefix.
                // Reserve the appropriate amount of space in the string.
                reserve(theName, DOMServices::s_XMLNamespaceWithSeparatorLength + length(thePrefix) + 1);

                theName = DOMServices::s_XMLNamespaceWithSeparator;
                theName += thePrefix;

                theNamespace.setResultAttributeName(theConstructionContext.getPooledString(theName));
            }
            else
            {
                // It's the default namespace...
                theNamespace.setResultAttributeName(DOMServices::s_XMLNamespace);
            }
        }
    }
}
XObjectPtr
FunctionHasSameNodes::execute(
            XPathExecutionContext&          executionContext,
            XalanNode*                      context,
            const XObjectArgVectorType&     args,
            const LocatorType*              locator) const
{
    if (args.size() != 2)
    {
        XPathExecutionContext::GetAndReleaseCachedString    theGuard(executionContext);

        executionContext.error(getError(theGuard.get()), context, locator);
    }

    assert(args[0].null() == false && args[1].null() == false);

    const NodeRefListBase&  nodeset1 = args[0]->nodeset();
    const NodeRefListBase&  nodeset2 = args[1]->nodeset();

    const NodeRefListBase::size_type    theLength = nodeset1.getLength();

    bool    fResult = true;

    if (theLength != nodeset2.getLength())
    {
        fResult = false;
    }
    else
    {
        for (NodeRefListBase::size_type i = 0; i < theLength && fResult == true; ++i)
        {
            XalanNode* const    theNode = nodeset1.item(i);
            assert(theNode != 0);

            if (nodeset2.indexOf(theNode) == NodeRefListBase::npos)
            {
                fResult = false;
            }
        }
    }

    return executionContext.getXObjectFactory().createBoolean(fResult);
}
XalanSourceTreeElementNANS*
XalanSourceTreeElementNANS::create(
            MemoryManagerType&                  theManager,
			const XalanSourceTreeElementNANS&	theSource,
			bool								deep) 
{
    typedef XalanSourceTreeElementNANS ThisType;

    XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType)));

    ThisType* theResult = theGuard.get();

    new (theResult) ThisType(theManager,
                            theSource,
                            deep);

    theGuard.release();

    return theResult;
}
XObjectPtr
FunctionString::execute(
            XPathExecutionContext&  executionContext,
            XalanNode*              context,
            const LocatorType*      locator) const
{
    if (context == 0)
    {
        XPathExecutionContext::GetAndReleaseCachedString    theGuard(executionContext);
        XalanDOMString&     theResult = theGuard.get();

        executionContext.error(
            XalanMessageLoader::getMessage(
                theResult,
                XalanMessages::FunctionRequiresNonNullContextNode_1Param,
                "string"),
            context,
            locator);

        // Dummy return value...
        return XObjectPtr();
    }
    else
    {
        // The XPath standard says that if there are no arguments,
        // the argument defaults to a node set with the context node
        // as the only member.  The string value of a node set is the
        // string value of the first node in the node set.
        // DOMServices::getNodeData() will give us the data.

        // Get a cached string...
        XPathExecutionContext::GetAndReleaseCachedString    theData(executionContext);

        XalanDOMString&     theString = theData.get();

        DOMServices::getNodeData(*context, theString);

        return executionContext.getXObjectFactory().createString(theData);
    }
}
XPathExecutionContextDefault*
XPathExecutionContextDefault::create(
            MemoryManager&          theManager,
            XalanNode*              theCurrentNode,
            const NodeRefListBase*  theContextNodeList,
            const PrefixResolver*   thePrefixResolver)
{
    typedef XPathExecutionContextDefault    ThisType;

    XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

    ThisType* const     theResult =
        new (theGuard.get()) ThisType(
                                theManager,
                                theCurrentNode,
                                theContextNodeList,
                                thePrefixResolver);

    theGuard.release();

    return theResult;
}
Ejemplo n.º 10
0
XALAN_CPP_NAMESPACE_BEGIN



XObjectPtr
XalanEXSLTFunctionEvaluate::execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const
{
	try
	{
		return ParentType::execute(executionContext, context, args, locator);
	}
	catch(const XSLException&)
	{
	}

	XPathExecutionContext::BorrowReturnMutableNodeRefList	theGuard(executionContext);

	return executionContext.getXObjectFactory().createNodeSet(theGuard);
}
Ejemplo n.º 11
0
void
AVT::nextToken(
            StylesheetConstructionContext&  constructionContext,
            const LocatorType*              locator,
            StringTokenizer&                tokenizer,
            XalanDOMString&                 token)
{
    if (tokenizer.hasMoreTokens() == false)
    {
        GetCachedString     theGuard(constructionContext);

        constructionContext.error(
            XalanMessageLoader::getMessage(
                theGuard.get(),
                XalanMessages::AttributeValueTemplateHasMissing),
            0,
            locator);
    }
    else
    {
        tokenizer.nextToken(token);
    }
}
XObjectPtr
XPathEvaluator::evaluate(
			DOMSupport&				domSupport,
			XalanNode*				contextNode,
			const XalanDOMChar*		xpathString,
			const PrefixResolver&	prefixResolver,
			XPathEnvSupport&		envSupport)
{
	assert(contextNode != 0);
	assert(xpathString != 0);

	// Create an XPath, and an XPathProcessorImpl to process
	// the XPath.
	XPath				theXPath(m_memoryManager);

	XPathProcessorImpl  theProcessor(m_memoryManager);

    GetAndReleaseCachedString   theGuard(*m_constructionContext.get());

    XalanDOMString&     theTempString = theGuard.get();

    theTempString = xpathString;

    theProcessor.initXPath(
			theXPath,
			*m_constructionContext.get(),
			theTempString,
			prefixResolver);

	return evaluate(
                domSupport,
                contextNode,
                theXPath,
                prefixResolver,
                envSupport);
}
XPath*
XPathEvaluator::createXPath(
			const XalanDOMChar*		xpathString,
			const PrefixResolver&	prefixResolver)
{
	XPath* const	theXPath = m_xpathFactory->create();
	assert(theXPath != 0);

	XPathProcessorImpl		theProcessor(m_memoryManager);

    GetAndReleaseCachedString   theGuard(*m_constructionContext.get());

    XalanDOMString&     theTempString = theGuard.get();

    theTempString = xpathString;

    theProcessor.initXPath(
			*theXPath,
			*m_constructionContext.get(),
			theTempString,
			prefixResolver);

	return theXPath;
}
Ejemplo n.º 14
0
void
ElemForEach::selectAndSortChildren(
			StylesheetExecutionContext&		executionContext,
			const ElemTemplateElement*		theTemplate,
			NodeSorter*						sorter,
			int								selectStackFrameIndex) const
{
	typedef StylesheetExecutionContext::SetAndRestoreCurrentStackFrameIndex		SetAndRestoreCurrentStackFrameIndex;

	assert(m_selectPattern != 0);

	typedef XPathExecutionContext::BorrowReturnMutableNodeRefList	BorrowReturnMutableNodeRefList;

	BorrowReturnMutableNodeRefList	theGuard(executionContext);

	const NodeRefListBase*	sourceNodes = 0;

	XObjectPtr				xobjectResult;

	{
		SetAndRestoreCurrentStackFrameIndex		theSetAndRestore(
					executionContext,
					selectStackFrameIndex);

		xobjectResult = m_selectPattern->execute(
						*this,
						executionContext,
						*theGuard);

		if (xobjectResult.null() == true)
		{
			sourceNodes = &*theGuard;
		}
		else
		{
			theGuard.release();

			sourceNodes = &xobjectResult->nodeset();
		}
	}

	if(0 != executionContext.getTraceListeners())
	{
		executionContext.fireSelectEvent(
				SelectionEvent(
					executionContext, 
					executionContext.getCurrentNode(),
					*this,
					StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("select")),
					*m_selectPattern,
					*sourceNodes));
	}

	const NodeRefListBase::size_type	nNodes = sourceNodes->getLength();

	if (nNodes > 0)
	{
		// If there's not NodeSorter, or we've only selected one node,
		// then just do the transform...
		if (sorter == 0 || nNodes == 1)
		{
			transformSelectedChildren(
				executionContext,
				theTemplate,
				*sourceNodes,
				nNodes);
		}
		else
		{
			typedef StylesheetExecutionContext::SetAndRestoreCurrentStackFrameIndex		SetAndRestoreCurrentStackFrameIndex;
			typedef StylesheetExecutionContext::ContextNodeListPushAndPop				ContextNodeListPushAndPop;
			typedef StylesheetExecutionContext::BorrowReturnMutableNodeRefList			BorrowReturnMutableNodeRefList;

			BorrowReturnMutableNodeRefList	sortedSourceNodes(executionContext);

			*sortedSourceNodes = *sourceNodes;

			{
				SetAndRestoreCurrentStackFrameIndex		theStackFrameSetAndRestore(
						executionContext,
						selectStackFrameIndex);

				ContextNodeListPushAndPop	theContextNodeListPushAndPop(
						executionContext,
						*sourceNodes);

				sorter->sort(executionContext, *sortedSourceNodes);
			}

			transformSelectedChildren(
				executionContext,
				theTemplate,
				*sortedSourceNodes,
				nNodes);
		}
	}
}
Ejemplo n.º 15
0
void
ElemLiteralResult::execute(StylesheetExecutionContext&	executionContext) const
{
	const XalanDOMString&	theElementName = getElementName();

	executionContext.startElement(c_wstr(theElementName));

	ElemUse::execute(executionContext);

	const NamespacesHandler&	theNamespacesHandler = getNamespacesHandler();

	theNamespacesHandler.outputResultNamespaces(executionContext);

	if (hasPrefix() == false)
	{
		// OK, let's check to make sure we don't have to change the default namespace...
		const XalanDOMString* const		theCurrentDefaultNamespace =
					executionContext.getResultNamespaceForPrefix(s_emptyString);

		if (theCurrentDefaultNamespace != 0)
		{
			const XalanDOMString* const		theElementDefaultNamespace =
							theNamespacesHandler.getNamespace(s_emptyString);

			if (theElementDefaultNamespace == 0)
			{
				// There was no default namespace, so we have to turn the
				// current one off.
				executionContext.addResultAttribute(DOMServices::s_XMLNamespace, s_emptyString);
			}
			else if (equals(*theCurrentDefaultNamespace, *theElementDefaultNamespace) == false)
			{
				executionContext.addResultAttribute(DOMServices::s_XMLNamespace, *theElementDefaultNamespace);
			}
		}
	}

	if(m_avtsCount > 0)
	{
		StylesheetExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		theStringedValue = theGuard.get();

		for(unsigned int i = 0; i < m_avtsCount; ++i)
		{
			const AVT* const	avt = m_avts[i];

			const XalanDOMString&	theName = avt->getName();

			avt->evaluate(theStringedValue, *this, executionContext);

			executionContext.addResultAttribute(theName, theStringedValue);

			theStringedValue.clear();
		}
	}

	executeChildren(executionContext);

	executionContext.endElement(c_wstr(theElementName));
}
Ejemplo n.º 16
0
bool
TestAxisResult(
            XPathProcessor&         theXPathProcessor,
            XPathEnvSupport&        theXPathEnvSupport,
            DOMSupport&             theDOMSupport,
            XMLParserLiaison&       theLiaison,
            XPathFactory&           theXPathFactory,
            const XalanDOMString&   theXMLFileURL,
            const XalanDOMString&   theXSLFileURL,
            PrintWriter&            thePrintWriter,
            XPathExecutionContext&  theExecutionContext)
{
    bool                    fError = false;

    XalanDocument* const    theXMLDocument = ParseXML(theLiaison,
                                                      theXMLFileURL);

    MemoryManagerType&      theMemoryManager =
        theExecutionContext.getMemoryManager();

    if (theXMLDocument != 0)
    {
        XalanDOMString      theContextNodeMatchPattern(theMemoryManager);
        XalanDOMString      theXPathString(theMemoryManager);

        if (GetXSLInput(theLiaison,
                        theXSLFileURL,
                        theContextNodeMatchPattern,
                        theXPathString,
                        theMemoryManager) == true)
        {
            XalanNode* const    theContextNode =
                FindContextNode(theXPathProcessor,
                                theXPathEnvSupport,
                                theDOMSupport,
                                theXPathFactory,
                                theXMLDocument,
                                theContextNodeMatchPattern,
                                thePrintWriter,
                                theExecutionContext);

            if (theContextNode != 0)
            {
                XalanElement* const             theNamespaceContext = 0;
                ElementPrefixResolverProxy      thePrefixResolver(theNamespaceContext, theXPathEnvSupport, theDOMSupport);
                NodeRefList                     theContextNodeList(theMemoryManager);

                XPath* const    theXPath = theXPathFactory.create();

                XPathConstructionContextDefault     theXPathConstructionContext(theMemoryManager);

                XPathGuard      theGuard(theXPathFactory,
                                         theXPath);

                theXPathProcessor.initXPath(*theXPath,
                                            theXPathConstructionContext,
                                            theXPathString,
                                            thePrefixResolver);

                bool    fDump = false;

                if (fDump == true)
                {
                    thePrintWriter.println();
                    thePrintWriter.println();
                    theXPath->getExpression().dumpOpCodeMap(thePrintWriter);
                    thePrintWriter.println();
                    theXPath->getExpression().dumpTokenQueue(thePrintWriter);
                    thePrintWriter.println();
                    thePrintWriter.println();
                }

                const XObjectPtr theResult =
                    theXPath->execute(theContextNode, thePrefixResolver, theContextNodeList, theExecutionContext);

                try
                {
                    assert(theResult.null() == false);

                    const NodeRefListBase&  theResultList =
                        theResult->nodeset();

                    const unsigned int  theLength = theResultList.getLength();

                    if (theLength == 0)
                    {
                        thePrintWriter.println("<out/>");
                    }
                    else
                    {
                        thePrintWriter.print("<out>");

                        for (unsigned int i = 0; i < theLength; i++)
                        {
                            thePrintWriter.print(theResultList.item(i)->getNodeName());
                            thePrintWriter.print(" ");
                        }

                        thePrintWriter.println("</out>");
                    }
                }
                catch(...)
                {
                    thePrintWriter.print("Execution of XPath ");
                    thePrintWriter.print(theXPathString);
                    thePrintWriter.println(" failed!");
                }
            }
        }
    }

    theLiaison.reset();

    return fError;
}
Ejemplo n.º 17
0
XalanNode*
FindContextNode(
            XPathProcessor&         theXPathProcessor,
            XPathEnvSupport&        theXPathEnvSupport,
            DOMSupport&             theDOMSupport,
            XPathFactory&           theXPathFactory,
            XalanDocument*          theDocument,
            const XalanDOMString&   theContextNodeMatchPattern,
            PrintWriter&            thePrintWriter,
            XPathExecutionContext&  theExecutionContext)
{
    XalanNode*      theResult = 0;

    MemoryManagerType&      theMemoryManager =
        theExecutionContext.getMemoryManager();

    XPath* const    theXPath = theXPathFactory.create();

    XPathConstructionContextDefault     theXPathConstructionContext;

    XPathGuard      theGuard(
                        theXPathFactory,
                        theXPath);

    XalanElement*               theNamespaceContext = 0;
    ElementPrefixResolverProxy  thePrefixResolver(theNamespaceContext, theXPathEnvSupport, theDOMSupport);
    NodeRefList                 theContextNodeList(theMemoryManager);

    const XObjectPtr    theXObject =
        ExecuteXPath(
            theXPathProcessor,
            theXPathConstructionContext,
            *theXPath,
            theContextNodeMatchPattern,
            theDocument,
            thePrefixResolver,
            theContextNodeList,
            theExecutionContext);

    try
    {
        assert(theXObject.null() == false);

        const NodeRefListBase&  theResultList =
                        theXObject->nodeset();

        if (theResultList.getLength() == 0)
        {
            thePrintWriter.print("FindContextNode: Unable to find context node using select \"");
            thePrintWriter.print(theContextNodeMatchPattern);
            thePrintWriter.println("\".");
            thePrintWriter.println("FindContextNode: No nodes matched the pattern.");
        }
        else if (theResultList.getLength() != 1)
        {
            thePrintWriter.print("FindContextNode: Unable to find context node using select \"");
            thePrintWriter.print(theContextNodeMatchPattern);
            thePrintWriter.println("\".");
            thePrintWriter.println("FindContextNode: More than one node matched the pattern.");
        }
        else
        {
            theResult = theResultList.item(0);
        }
    }
    catch(...)
    {
        thePrintWriter.print("FindContextNode: Error executing match pattern \"");
        thePrintWriter.print(theContextNodeMatchPattern);
        thePrintWriter.println("\".");
    }

    return theResult;
}
Ejemplo n.º 18
0
/**
 * Construct an AVT by parsing the string, and either 
 * constructing a vector of AVTParts, or simply hold 
 * on to the string if the AVT is simple.
 */
AVT::AVT(
            StylesheetConstructionContext&  constructionContext,
            const LocatorType*              locator,
            const XalanDOMChar*             name,
            const XalanDOMChar*             stringedValue,
            const PrefixResolver&           resolver) :
        m_parts(0),
        m_partsSize(0),
        m_simpleString(0),
        m_simpleStringLength(0),
        m_name(constructionContext.getPooledString(name))
{
    StringTokenizer     tokenizer(stringedValue, theTokenDelimiterCharacters, true);

    const StringTokenizer::size_type    nTokens = tokenizer.countTokens();

    if(nTokens < 2)
    {
        // Do the simple thing
        m_simpleStringLength = length(stringedValue);

        m_simpleString = constructionContext.allocateXalanDOMCharVector(stringedValue, m_simpleStringLength, false);
    }
    else
    {
        // This over-allocates, but we probably won't waste that much space.  If necessary,
        // we could tokenize twice, just counting the numbers of AVTPart instances we
        // will need the first time.
        m_parts = constructionContext.allocateAVTPartPointerVector(nTokens + 1);

        XalanDOMString  buffer(constructionContext.getMemoryManager());
        XalanDOMString  exprBuffer(constructionContext.getMemoryManager());
        XalanDOMString  t(constructionContext.getMemoryManager()); // base token
        XalanDOMString  lookahead(constructionContext.getMemoryManager()); // next token

        while(tokenizer.hasMoreTokens())
        {
            if(length(lookahead))
            {
                t = lookahead;

                clear(lookahead);
            }
            else
            {
                nextToken(constructionContext, locator, tokenizer, t);
            }

            if(length(t) == 1)
            {
                const XalanDOMChar  theChar = charAt(t, 0);

                switch(theChar)
                {
                    case(XalanUnicode::charLeftCurlyBracket):
                    {
                        // Attribute Value Template start
                        nextToken(constructionContext, locator, tokenizer, lookahead);

                        if(equals(lookahead, theLeftCurlyBracketString))
                        {
                            // Double braces mean escape to show brace
                            append(buffer, lookahead);

                            clear(lookahead);

                            break; // from switch
                        }
                        else
                        {
                            if(length(buffer) > 0)
                            {
                                assert(m_partsSize + 1 < nTokens);

                                m_parts[m_partsSize++] =
                                    constructionContext.createAVTPart(
                                        c_wstr(buffer),
                                        length(buffer));

                                clear(buffer);
                            }
                                    
                            clear(exprBuffer);

                            while(length(lookahead) > 0 && !equals(lookahead, theRightCurlyBracketString))
                            {
                                if(length(lookahead) == 1)
                                {
                                    switch(charAt(lookahead, 0))
                                    {
                                        case XalanUnicode::charApostrophe:
                                        case XalanUnicode::charQuoteMark:
                                        {
                                            // String start
                                            append(exprBuffer, lookahead);

                                            const XalanDOMChar  quote[2] =
                                            {
                                                lookahead[0],
                                                0
                                            };

                                            // Consume stuff 'till next quote
                                            nextToken(constructionContext, locator, tokenizer, lookahead);

                                            while(!equals(lookahead, quote))
                                            {
                                                append(exprBuffer, lookahead);

                                                nextToken(constructionContext, locator, tokenizer, lookahead);
                                            }

                                            append(exprBuffer,lookahead);

                                            break;
                                        }

                                        case XalanUnicode::charLeftCurlyBracket:
                                            {
                                                GetCachedString     theGuard(constructionContext);

                                                // What's another brace doing here?
                                                constructionContext.error(
                                                    XalanMessageLoader::getMessage(
                                                        theGuard.get(),
                                                        XalanMessages::LeftBraceCannotAppearWithinExpression),
                                                    0,
                                                    locator);
                                                break;
                                            }

                                        default:
                                            // part of the template stuff, just add it.
                                            append(exprBuffer, lookahead);
                                            break;

                                    } // end inner switch
                                } // end if lookahead length == 1
                                else
                                {
                                    // part of the template stuff, just add it.
                                    append(exprBuffer,lookahead);
                                }

                                nextToken(constructionContext, locator, tokenizer, lookahead);
                            } // end while(!equals(lookahead, "}"))
                            assert(equals(lookahead, theRightCurlyBracketString));

                            // Proper close of attribute template. Evaluate the
                            // expression.
                            clear(buffer);

                            assert(m_partsSize + 1 < nTokens);

                            m_parts[m_partsSize++] =
                                constructionContext.createAVTPart(
                                    locator,
                                    c_wstr(exprBuffer),
                                    length(exprBuffer),
                                    resolver);

                            clear(lookahead); // breaks out of inner while loop
                        }
                        break;
                    }
                    case(XalanUnicode::charRightCurlyBracket):
                    {
                        nextToken(constructionContext, locator, tokenizer, lookahead);

                        if(equals(lookahead, theRightCurlyBracketString))
                        {
                            // Double brace mean escape to show brace
                            append(buffer, lookahead);

                            clear(lookahead); // swallow
                        }
                        else
                        {
                            GetCachedString     theGuard(constructionContext);

                            constructionContext.error(
                                XalanMessageLoader::getMessage(
                                    theGuard.get(),
                                    XalanMessages::UnmatchedWasFound),
                                0,
                                locator);

                        }
                        break;
                    }
                    default:
                    {
                        // Anything else just add to string.
                        append(buffer, theChar);
                    }
                } // end switch t
            } // end if length == 1
            else
            {
                // Anything else just add to string.
                append(buffer,t);
            }
        } // end while(tokenizer.hasMoreTokens())

        if(length(buffer) > 0)
        {
            assert(m_partsSize + 1 < nTokens);

            m_parts[m_partsSize++] = constructionContext.createAVTPart(c_wstr(buffer), length(buffer));

            clear(buffer);
        }
    } // end else nTokens > 1
}