int main(int argc, char *argv[]) { // Initialise Xerces-C and XQilla by creating the factory object XQilla xqilla; // Parse an XQuery expression // (AutoDelete deletes the object at the end of the scope) AutoDelete<XQQuery> query(xqilla.parse(X("foo/bar/@baz"))); // Create a context object AutoDelete<DynamicContext> context(query->createDynamicContext()); // Parse a document, and set it as the context item Sequence seq = context->resolveDocument(X("foo.xml")); if(!seq.isEmpty() && seq.first()->isNode()) { context->setContextItem(seq.first()); context->setContextPosition(1); context->setContextSize(1); } // Execute the query, using the context Result result = query->execute(context); // Iterate over the results, printing them Item::Ptr item; while(item = result->next(context)) { std::cout << UTF8(item->asString(context)) << std::endl; } return 0; }
Sequence FunctionCompare::createSequence(DynamicContext* context, int flags) const { Sequence str1 = getParamNumber(1,context)->toSequence(context); Sequence str2 = getParamNumber(2,context)->toSequence(context); if(str1.isEmpty() || str2.isEmpty()) return Sequence(context->getMemoryManager()); Collation* collation = NULL; if(getNumArgs()>2) { Sequence collArg = getParamNumber(3,context)->toSequence(context); const XMLCh* collName = collArg.first()->asString(context); try { context->getItemFactory()->createAnyURI(collName, context); } catch(XPath2ErrorException &e) { XQThrow(FunctionException, X("FunctionCompare::createSequence"), X("Invalid argument to compare function")); } collation = context->getCollation(collName, this); if(collation == NULL) XQThrow(FunctionException,X("FunctionCompare::createSequence"),X("Collation object is not available")); } else collation = context->getDefaultCollation(this); if(collation == NULL) collation = context->getCollation(CodepointCollation::getCodepointCollationName(), this); const XMLCh* string1 = str1.first()->asString(context); const XMLCh* string2 = str2.first()->asString(context); Sequence result(context->getItemFactory()->createInteger(collation->compare(string1,string2), context), context->getMemoryManager()); return result; }
void XercesUpdateFactory::addToPutSet(const Node::Ptr &node, const LocationInfo *location, DynamicContext *context) { Node::Ptr root = node->root(context); Sequence docURISeq = root->dmDocumentURI(context); const XMLCh *docuri = 0; if(!docURISeq.isEmpty()) { docuri = docURISeq.first()->asString(context); } PutItem item(docuri, root, location, context); std::pair<PutSet::iterator, bool> res = putSet_.insert(item); if(!res.second && !res.first->node->equals(item.node)) { if(context->getMessageListener() != 0) { context->getMessageListener()->warning(X("In the context of this expression"), res.first->location); } XMLBuffer buf; buf.append(X("Document writing conflict for URI \"")); buf.append(item.uri); buf.append(X("\"")); XQThrow3(ASTException, X("XercesUpdateFactory::addToPutSet"), buf.getRawBuffer(), location); } }
Sequence FunctionDocAvailable::createSequence(DynamicContext* context, int flags) const { Sequence uriArg = getParamNumber(1,context)->toSequence(context); if (uriArg.isEmpty()) { return Sequence(context->getMemoryManager()); } const XMLCh* uri = uriArg.first()->asString(context); // on Windows, we can have URIs using \ instead of /; let's normalize them XMLCh backSlash[]={ XERCES_CPP_NAMESPACE_QUALIFIER chBackSlash, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; if(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::findAny(uri,backSlash)) { XMLCh* newUri=XERCES_CPP_NAMESPACE_QUALIFIER XMLString::replicate(uri,context->getMemoryManager()); for(unsigned int i=0;i<XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(newUri);i++) if(newUri[i]==XERCES_CPP_NAMESPACE_QUALIFIER chBackSlash) newUri[i]=XERCES_CPP_NAMESPACE_QUALIFIER chForwardSlash; uri=newUri; } if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionDocAvailable::createSequence"), X("Invalid argument to fn:doc-available function [err:FODC0005]")); bool bSuccess=false; try { bSuccess = !context->resolveDocument(uri, this).isEmpty(); } catch(...) { } return Sequence(context->getItemFactory()->createBoolean(bSuccess, context), context->getMemoryManager()); }
BoolResult FunctionContains::boolResult(DynamicContext* context) const { Sequence str1 = getParamNumber(1,context)->toSequence(context); Sequence str2 = getParamNumber(2,context)->toSequence(context); Collation* collation = NULL; if(getNumArgs()>2) { Sequence collArg = getParamNumber(3,context)->toSequence(context); const XMLCh* collName = collArg.first()->asString(context); try { context->getItemFactory()->createAnyURI(collName, context); } catch(XPath2ErrorException &e) { XQThrow(FunctionException, X("FunctionContains::createSequence"), X("Invalid collationURI")); } collation=context->getCollation(collName, this); if(collation==NULL) XQThrow(FunctionException,X("FunctionContains::createSequence"),X("Collation object is not available")); } else collation=context->getCollation(CodepointCollation::getCodepointCollationName(), this); const XMLCh* container = XMLUni::fgZeroLenString; if(!str1.isEmpty()) container=str1.first()->asString(context); const XMLCh* pattern = XMLUni::fgZeroLenString; if(!str2.isEmpty()) pattern=str2.first()->asString(context); if(XMLString::stringLen(pattern)==0) return true; else if(XMLString::stringLen(container)==0) return false; return XMLString::patternMatch(container, pattern) > -1; }
BoolResult FunctionDocAvailable::boolResult(DynamicContext* context) const { Sequence uriArg = getParamNumber(1,context)->toSequence(context); if (uriArg.isEmpty()) return false; const XMLCh* uri = uriArg.first()->asString(context); // on Windows, we can have URIs using \ instead of /; let's normalize them XMLCh backSlash[]={ chBackSlash, chNull }; if(XMLString::findAny(uri,backSlash)) { XMLCh* newUri=XMLString::replicate(uri,context->getMemoryManager()); for(unsigned int i=0;i<XMLString::stringLen(newUri);i++) if(newUri[i]==chBackSlash) newUri[i]=chForwardSlash; uri=newUri; } if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionDocAvailable::createSequence"), X("Invalid argument to fn:doc-available function [err:FODC0005]")); try { return !context->resolveDocument(uri, this).isEmpty(); } catch(...) { } return false; }
BoolResult FunctionEndsWith::boolResult(DynamicContext* context) const { Sequence sourceString=getParamNumber(1,context)->toSequence(context); Sequence findString=getParamNumber(2,context)->toSequence(context); const XMLCh* source = XMLUni::fgZeroLenString; if(!sourceString.isEmpty()) source=sourceString.first()->asString(context); const XMLCh* find = XMLUni::fgZeroLenString; if(!findString.isEmpty()) find=findString.first()->asString(context); // If the value of $operand1 is the zero-length string and the value of $operand2 is not the zero-length string, // then the function returns false. if(XMLString::stringLen(source)==0 && XMLString::stringLen(find)>0) return false; // If the value of $operand2 is the zero-length string, then the function returns true if(XMLString::stringLen(find)==0) return true; Collation* collation=NULL; if(getNumArgs()>2) { Sequence collArg = getParamNumber(3,context)->toSequence(context); const XMLCh* collName = collArg.first()->asString(context); try { context->getItemFactory()->createAnyURI(collName, context); } catch(XPath2ErrorException &e) { XQThrow(FunctionException, X("FunctionEndsWith::createSequence"), X("Invalid collationURI")); } collation=context->getCollation(collName, this); } else collation=context->getDefaultCollation(this); // Returns a boolean indicating whether or not the value of $operand1 ends with a string that is equal to the value // of $operand2 according to the specified collation if(XMLString::stringLen(find)>XMLString::stringLen(source)) return false; int i,j; // for(i = XMLString::stringLen(source)-1, j=XMLString::stringLen(find)-1; i >=0 && j >=0; i--,j--) for(i = XPath2Utils::intStrlen(source)-1, j=XPath2Utils::intStrlen(find)-1; i >=0 && j >=0; i--,j--) { const XMLCh *string1 = XPath2Utils::subString(source, i,1, context->getMemoryManager()); const XMLCh *string2 = XPath2Utils::subString(find, j, 1, context->getMemoryManager()); bool result = (collation->compare(string1, string2)!=0); if(result) { return false; } } return true; }
Sequence FunctionQName::createSequence(DynamicContext* context, int flags) const { Sequence paramURIseq = getParamNumber(1, context)->toSequence(context); Sequence paramLocalseq = getParamNumber(2, context)->toSequence(context); const XMLCh* uri = NULL; if(!paramURIseq.isEmpty()) uri=paramURIseq.first()->asString(context); const XMLCh* local = paramLocalseq.first()->asString(context); if(!XERCES_CPP_NAMESPACE_QUALIFIER XMLChar1_0::isValidQName(local, XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(local))) XQThrow(FunctionException,X("FunctionQName::createSequence"),X("The second argument to fn:QName is not a valid xs:QName [err:FOCA0002]")); const XMLCh* prefix = XPath2NSUtils::getPrefix(local, context->getMemoryManager()); if((uri==NULL || *uri==0) && !(prefix==NULL || *prefix==0)) XQThrow(FunctionException,X("FunctionQName::createSequence"),X("The second argument to fn:QName specifies a prefix, but the specified uri is empty [err:FOCA0002]")); local = XPath2NSUtils::getLocalName(local); //Construct QName here Sequence result(context->getItemFactory()->createQName(uri, prefix, local, context), context->getMemoryManager()); return result; }
Sequence DbXmlDocAvailable::createSequence(DynamicContext* context, int flags) const { const XMLCh* currentUri = getUriArg(context); DbXmlUri uri(context->getBaseURI(), currentUri, /*documentUri*/true); if(uri.isDbXmlScheme()) { if(uri.getDocumentName() != "") { try { DbXmlConfiguration *conf = GET_CONFIGURATION(context); OperationContext &oc = conf->getOperationContext(); XmlContainer containerWrapper = uri.openContainer(conf->getManager(), oc.txn()); // Perform a presence lookup on the built-in node-metadata-equality-string // index for the document name AutoDelete<NodeIterator> result(((Container*)containerWrapper)-> createDocumentIterator(context, this, uri.getDocumentName().c_str(), uri.getDocumentName().length())); return Sequence(context->getItemFactory()-> createBoolean(result->next(context), context), context->getMemoryManager()); } catch(XmlException &) {} } return Sequence(context->getItemFactory()->createBoolean(false, context), context->getMemoryManager()); } // Revert to the default behaviour try { Sequence seq = context->resolveDocument(currentUri, this); if(!seq.isEmpty()) { // Force the lazy DbXmlNodeImpl to parse the document, // to check that it actually exists and is valid. const Item *item = seq.first(); const DbXmlNodeImpl *impl = (const DbXmlNodeImpl*)item->getInterface(DbXmlNodeImpl::gDbXml); DBXML_ASSERT(impl); impl->getNsDomNode(); return Sequence(context->getItemFactory()->createBoolean(true, context), context->getMemoryManager()); } } catch(...) {} return Sequence(context->getItemFactory()->createBoolean(false, context), context->getMemoryManager()); }
RecipeReader::RecipeReader(std::string filename) { XQilla xqilla; try{ AutoDelete<XQQuery> qinit(xqilla.parse(X("data(/cooker/init)"))); AutoDelete<DynamicContext> context (qinit->createDynamicContext()); Sequence seq = context->resolveDocument(X(filename.c_str())); if(!seq.isEmpty() && seq.first()->isNode()) { context->setContextItem(seq.first()); context->setContextPosition(1); context->setContextSize(1); } Result rinit=qinit->execute(context); InitXML=UTF8(rinit->next(context)->asString(context)); AutoDelete<XQQuery> qsrctree(xqilla.parse(X("data(/cooker/source)"))); Result rsrctree=qsrctree->execute(context); srctree=UTF8(rsrctree->next(context)->asString(context)); AutoDelete<XQQuery> qdsttree(xqilla.parse(X("data(/cooker/destination)"))); Result rdsttree=qdsttree->execute(context); dsttree=UTF8(rdsttree->next(context)->asString(context)); AutoDelete<XQQuery> qplugs(xqilla.parse(X("/cooker/plugins/plugin"))); Result rplugs=qplugs->execute(context); AutoDelete<XQQuery> qplname(xqilla.parse(X("data(./name)"))); AutoDelete<XQQuery> qplfile(xqilla.parse(X("data(./file)"))); AutoDelete<DynamicContext> context2 (qplname->createDynamicContext()); while(Node::Ptr item=rplugs->next(context)) { context2->setContextItem(item); context2->setContextPosition(1); context2->setContextSize(1); Result rname=qplname->execute(context2); Result rfile=qplfile->execute(context2); plugins[UTF8(rname->next(context2)->asString(context2))]=UTF8(rfile->next(context2)->asString(context2)); } AutoDelete<XQQuery> qdefineHistograms(xqilla.parse(X("/cooker/defineHistograms/*"))); Result rdefineHistograms=qdefineHistograms->execute(context); while(Node::Ptr item=rdefineHistograms->next(context)) { defineHistograms.push_back(class_method(UTF8(item->dmNodeName(context)->getName()), UTF8(item->dmStringValue(context)))); } AutoDelete<XQQuery> qstartup(xqilla.parse(X("/cooker/startup/*"))); Result rstartup=qstartup->execute(context); while(Node::Ptr item=rstartup->next(context)) { startup.push_back(class_method(UTF8(item->dmNodeName(context)->getName()), UTF8(item->dmStringValue(context)))); } AutoDelete<XQQuery> qexecute(xqilla.parse(X("/cooker/execute/*"))); Result rexecute=qexecute->execute(context); while(Node::Ptr item=rexecute->next(context)) { commands.push_back(class_method(UTF8(item->dmNodeName(context)->getName()), UTF8(item->dmStringValue(context)))); } AutoDelete<XQQuery> qfinalize(xqilla.parse(X("/cooker/finalize/*"))); Result rfinalize=qfinalize->execute(context); while(Node::Ptr item=rfinalize->next(context)) { finalize.push_back(class_method(UTF8(item->dmNodeName(context)->getName()), UTF8(item->dmStringValue(context)))); } } catch( XQException E) { std::cerr<<"Parsing of recipe XML failed, error type:"<<UTF8(E.getType())<<" Error:"<<UTF8(E.getError())<<std::endl; } }