nsresult txPatternParser::createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; bool isAttr = false; Token* tok = aLexer.peek(); if (tok->mType == Token::AXIS_IDENTIFIER) { if (TX_StringEqualsAtom(tok->Value(), nsGkAtoms::attribute)) { isAttr = true; } else if (!TX_StringEqualsAtom(tok->Value(), nsGkAtoms::child)) { // all done already for CHILD_AXIS, for all others // XXX report unexpected axis error return NS_ERROR_XPATH_PARSE_FAILURE; } aLexer.nextToken(); } else if (tok->mType == Token::AT_SIGN) { aLexer.nextToken(); isAttr = true; } txNodeTest* nodeTest; if (aLexer.peek()->mType == Token::CNAME) { tok = aLexer.nextToken(); // resolve QName RefPtr<nsAtom> prefix, lName; int32_t nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, true); if (NS_FAILED(rv)) { // XXX error report namespace resolve failed return rv; } uint16_t nodeType = isAttr ? (uint16_t)txXPathNodeType::ATTRIBUTE_NODE : (uint16_t)txXPathNodeType::ELEMENT_NODE; nodeTest = new txNameTest(prefix, lName, nspace, nodeType); } else { rv = createNodeTypeTest(aLexer, &nodeTest); NS_ENSURE_SUCCESS(rv, rv); } nsAutoPtr<txStepPattern> step(new txStepPattern(nodeTest, isAttr)); rv = parsePredicates(step, aLexer, aContext); NS_ENSURE_SUCCESS(rv, rv); aPattern = step.forget(); return NS_OK; }
//static bool XMLUtils::getXMLSpacePreserve(const txXPathNode& aNode) { nsAutoString value; txXPathTreeWalker walker(aNode); do { if (walker.getAttr(nsGkAtoms::space, kNameSpaceID_XML, value)) { if (TX_StringEqualsAtom(value, nsGkAtoms::preserve)) { return true; } if (TX_StringEqualsAtom(value, nsGkAtoms::_default)) { return false; } } } while (walker.moveToParent()); return false; }
nsresult txAttribute::execute(txExecutionState& aEs) { nsAutoString name; nsresult rv = mName->evaluateToString(aEs.getEvalContext(), name); NS_ENSURE_SUCCESS(rv, rv); const PRUnichar* colon; if (!XMLUtils::isValidQName(name, &colon) || TX_StringEqualsAtom(name, nsGkAtoms::xmlns)) { return NS_OK; } nsCOMPtr<nsIAtom> prefix; PRUint32 lnameStart = 0; if (colon) { prefix = do_GetAtom(Substring(name.get(), colon)); lnameStart = colon - name.get() + 1; } PRInt32 nsId = kNameSpaceID_None; if (mNamespace) { nsAutoString nspace; rv = mNamespace->evaluateToString(aEs.getEvalContext(), nspace); NS_ENSURE_SUCCESS(rv, rv); if (!nspace.IsEmpty()) { nsId = txNamespaceManager::getNamespaceID(nspace); } } else if (colon) { nsId = mMappings->lookupNamespace(prefix); } nsAutoPtr<txTextHandler> handler( static_cast<txTextHandler*>(aEs.popResultHandler())); // add attribute if everything was ok return nsId != kNameSpaceID_Unknown ? aEs.mResultHandler->attribute(prefix, Substring(name, lnameStart), nsId, handler->mValue) : NS_OK; }
nsresult txPatternParser::createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; MBool isAttr = MB_FALSE; Token* tok = aLexer.peek(); if (tok->mType == Token::AXIS_IDENTIFIER) { if (TX_StringEqualsAtom(tok->Value(), txXPathAtoms::attribute)) { isAttr = MB_TRUE; } else if (!TX_StringEqualsAtom(tok->Value(), txXPathAtoms::child)) { // all done already for CHILD_AXIS, for all others // XXX report unexpected axis error return NS_ERROR_XPATH_PARSE_FAILURE; } aLexer.nextToken(); } else if (tok->mType == Token::AT_SIGN) { aLexer.nextToken(); isAttr = MB_TRUE; } tok = aLexer.nextToken(); txNodeTest* nodeTest; if (tok->mType == Token::CNAME) { // resolve QName nsCOMPtr<nsIAtom> prefix, lName; PRInt32 nspace; rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, PR_TRUE); if (NS_FAILED(rv)) { // XXX error report namespace resolve failed return rv; } PRUint16 nodeType = isAttr ? (PRUint16)txXPathNodeType::ATTRIBUTE_NODE : (PRUint16)txXPathNodeType::ELEMENT_NODE; nodeTest = new txNameTest(prefix, lName, nspace, nodeType); if (!nodeTest) { return NS_ERROR_OUT_OF_MEMORY; } } else { aLexer.pushBack(); rv = createNodeTypeTest(aLexer, &nodeTest); NS_ENSURE_SUCCESS(rv, rv); } nsAutoPtr<txStepPattern> step(new txStepPattern(nodeTest, isAttr)); if (!step) { delete nodeTest; return NS_ERROR_OUT_OF_MEMORY; } rv = parsePredicates(step, aLexer, aContext); NS_ENSURE_SUCCESS(rv, rv); aPattern = step.forget(); return NS_OK; }
nsresult txNodeSorter::addSortElement(Expr* aSelectExpr, Expr* aLangExpr, Expr* aDataTypeExpr, Expr* aOrderExpr, Expr* aCaseOrderExpr, txIEvalContext* aContext) { nsAutoPtr<SortKey> key(new SortKey); NS_ENSURE_TRUE(key, NS_ERROR_OUT_OF_MEMORY); nsresult rv = NS_OK; // Select key->mExpr = aSelectExpr; // Order MBool ascending = MB_TRUE; if (aOrderExpr) { nsAutoString attrValue; rv = aOrderExpr->evaluateToString(aContext, attrValue); NS_ENSURE_SUCCESS(rv, rv); if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::descending)) { ascending = MB_FALSE; } else if (!TX_StringEqualsAtom(attrValue, txXSLTAtoms::ascending)) { // XXX ErrorReport: unknown value for order attribute return NS_ERROR_XSLT_BAD_VALUE; } } // Create comparator depending on datatype nsAutoString dataType; if (aDataTypeExpr) { rv = aDataTypeExpr->evaluateToString(aContext, dataType); NS_ENSURE_SUCCESS(rv, rv); } if (!aDataTypeExpr || TX_StringEqualsAtom(dataType, txXSLTAtoms::text)) { // Text comparator // Language nsAutoString lang; if (aLangExpr) { rv = aLangExpr->evaluateToString(aContext, lang); NS_ENSURE_SUCCESS(rv, rv); } // Case-order MBool upperFirst = PR_FALSE; if (aCaseOrderExpr) { nsAutoString attrValue; rv = aCaseOrderExpr->evaluateToString(aContext, attrValue); NS_ENSURE_SUCCESS(rv, rv); if (TX_StringEqualsAtom(attrValue, txXSLTAtoms::upperFirst)) { upperFirst = PR_TRUE; } else if (!TX_StringEqualsAtom(attrValue, txXSLTAtoms::lowerFirst)) { // XXX ErrorReport: unknown value for case-order attribute return NS_ERROR_XSLT_BAD_VALUE; } } key->mComparator = new txResultStringComparator(ascending, upperFirst, lang); NS_ENSURE_TRUE(key->mComparator, NS_ERROR_OUT_OF_MEMORY); } else if (TX_StringEqualsAtom(dataType, txXSLTAtoms::number)) { // Number comparator key->mComparator = new txResultNumberComparator(ascending); NS_ENSURE_TRUE(key->mComparator, NS_ERROR_OUT_OF_MEMORY); } else { // XXX ErrorReport: unknown data-type return NS_ERROR_XSLT_BAD_VALUE; } // mSortKeys owns key now. rv = mSortKeys.add(key); NS_ENSURE_SUCCESS(rv, rv); key.forget(); mNKeys++; return NS_OK; }
nsresult txStylesheetCompiler::startElementInternal(PRInt32 aNamespaceID, nsIAtom* aLocalName, nsIAtom* aPrefix, txStylesheetAttr* aAttributes, PRInt32 aAttrCount, PRInt32 aIDOffset) { nsresult rv = NS_OK; PRInt32 i; for (i = mInScopeVariables.Length() - 1; i >= 0; --i) { ++mInScopeVariables[i]->mLevel; } // Update the elementcontext if we have special attributes for (i = 0; i < aAttrCount; ++i) { txStylesheetAttr* attr = aAttributes + i; // xml:space if (attr->mNamespaceID == kNameSpaceID_XML && attr->mLocalName == nsGkAtoms::space) { rv = ensureNewElementContext(); NS_ENSURE_SUCCESS(rv, rv); if (TX_StringEqualsAtom(attr->mValue, nsGkAtoms::preserve)) { mElementContext->mPreserveWhitespace = MB_TRUE; } else if (TX_StringEqualsAtom(attr->mValue, nsGkAtoms::_default)) { mElementContext->mPreserveWhitespace = MB_FALSE; } else { return NS_ERROR_XSLT_PARSE_FAILURE; } } // xml:base if (attr->mNamespaceID == kNameSpaceID_XML && attr->mLocalName == nsGkAtoms::base && !attr->mValue.IsEmpty()) { rv = ensureNewElementContext(); NS_ENSURE_SUCCESS(rv, rv); nsAutoString uri; URIUtils::resolveHref(attr->mValue, mElementContext->mBaseURI, uri); mElementContext->mBaseURI = uri; } // extension-element-prefixes if ((attr->mNamespaceID == kNameSpaceID_XSLT && attr->mLocalName == nsGkAtoms::extensionElementPrefixes && aNamespaceID != kNameSpaceID_XSLT) || (attr->mNamespaceID == kNameSpaceID_None && attr->mLocalName == nsGkAtoms::extensionElementPrefixes && aNamespaceID == kNameSpaceID_XSLT && (aLocalName == nsGkAtoms::stylesheet || aLocalName == nsGkAtoms::transform))) { rv = ensureNewElementContext(); NS_ENSURE_SUCCESS(rv, rv); nsWhitespaceTokenizer tok(attr->mValue); while (tok.hasMoreTokens()) { PRInt32 namespaceID = mElementContext->mMappings-> lookupNamespaceWithDefault(tok.nextToken()); if (namespaceID == kNameSpaceID_Unknown) return NS_ERROR_XSLT_PARSE_FAILURE; if (!mElementContext->mInstructionNamespaces. AppendElement(namespaceID)) { return NS_ERROR_OUT_OF_MEMORY; } } attr->mLocalName = nsnull; } // version if ((attr->mNamespaceID == kNameSpaceID_XSLT && attr->mLocalName == nsGkAtoms::version && aNamespaceID != kNameSpaceID_XSLT) || (attr->mNamespaceID == kNameSpaceID_None && attr->mLocalName == nsGkAtoms::version && aNamespaceID == kNameSpaceID_XSLT && (aLocalName == nsGkAtoms::stylesheet || aLocalName == nsGkAtoms::transform))) { rv = ensureNewElementContext(); NS_ENSURE_SUCCESS(rv, rv); if (attr->mValue.EqualsLiteral("1.0")) { mElementContext->mForwardsCompatibleParsing = MB_FALSE; } else { mElementContext->mForwardsCompatibleParsing = MB_TRUE; } } } // Find the right elementhandler and execute it MBool isInstruction = MB_FALSE; PRInt32 count = mElementContext->mInstructionNamespaces.Length(); for (i = 0; i < count; ++i) { if (mElementContext->mInstructionNamespaces[i] == aNamespaceID) { isInstruction = MB_TRUE; break; } } if (mEmbedStatus == eNeedEmbed) { // handle embedded stylesheets if (aIDOffset >= 0 && aAttributes[aIDOffset].mValue.Equals(mTarget)) { // We found the right ID, signal to compile the // embedded stylesheet. mEmbedStatus = eInEmbed; } } const txElementHandler* handler; do { handler = isInstruction ? mHandlerTable->find(aNamespaceID, aLocalName) : mHandlerTable->mLREHandler; rv = (handler->mStartFunction)(aNamespaceID, aLocalName, aPrefix, aAttributes, aAttrCount, *this); } while (rv == NS_XSLT_GET_NEW_HANDLER); NS_ENSURE_SUCCESS(rv, rv); if (!fcp()) { for (i = 0; i < aAttrCount; ++i) { txStylesheetAttr& attr = aAttributes[i]; if (attr.mLocalName && (attr.mNamespaceID == kNameSpaceID_XSLT || (aNamespaceID == kNameSpaceID_XSLT && attr.mNamespaceID == kNameSpaceID_None))) { // XXX ErrorReport: unknown attribute return NS_ERROR_XSLT_PARSE_FAILURE; } } } rv = pushPtr(const_cast<txElementHandler*>(handler)); NS_ENSURE_SUCCESS(rv, rv); mElementContext->mDepth++; return NS_OK; }