ContainerBase *LookupIndexFunction::getContainerArg(DynamicContext *context, bool lookup) const { if(container_ != 0) return container_; if(!_args[0]->isConstant() && !lookup) return 0; DbXmlConfiguration *conf = GET_CONFIGURATION(context); Item::Ptr containerName = getParamNumber(1, context)->next(context); try { XmlContainer container = DbXmlUri::openContainer(XMLChToUTF8(containerName->asString(context)).str(), conf->getManager(), conf->getTransaction()); Container *tcont = (Container*)container; conf->getMinder()->addContainer(tcont); return tcont; } catch(XmlException &e) { e.setLocationInfo(this); throw; } // Never reached return 0; }
Sequence FunctionDocument::createSequence(DynamicContext* context, int flags) const { const XMLCh *baseURI; if(getNumArgs() == 2) { baseURI = ((Node*)getParamNumber(2, context)->next(context).get())->dmBaseURI(context).first()->asString(context); } else { baseURI = context->getBaseURI(); } Sequence result(context->getMemoryManager()); Result args = getParamNumber(1, context); Item::Ptr uriArg; while((uriArg = args->next(context)).notNull()) { const XMLCh *uri = uriArg->asString(context); if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionDocument::createSequence"), X("Invalid argument to fn:document function [err:FODC0005]")); try { XMLUri base(baseURI); XMLUri full(&base, uri); uri = context->getMemoryManager()->getPooledString(full.getUriText()); } catch(MalformedURLException &e){ XQThrow(FunctionException, X("FunctionDocument::createSequence"), X("Invalid argument to resolve-uri [err:FORG0002]")); } result.joinSequence(context->resolveDocument(uri, this, context->getProjection() ? queryPathTree_ : 0)); } return result; }
Sequence FunctionSentences::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); // If the value of $operand1 is the empty sequence, the empty sequence is returned. Item::Ptr inputString = getParamNumber(1,context)->next(context); if(inputString.isNull()) return Sequence(memMgr); const XMLCh *input=inputString->asString(context); AutoDeallocate<XMLCh> buf(UnicodeTransformer::sentences(input, memMgr), memMgr); XMLCh* rb = buf.get(); XMLCh* start = NULL; Sequence resultSeq(0, memMgr); // Build sequence for (int i = 0; rb[i]; i++) { if (rb[i] != UTF8PROC_SB_MARK) continue; rb[i] = 0; if (rb[i+1] == 0 || rb[i+1] != UTF8PROC_SB_MARK) { if (start != NULL) resultSeq.addItem(context->getItemFactory()->createString(start, context)); start = rb + (i+1); } } return resultSeq; }
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 FunctionDoc::createSequence(DynamicContext* context, int flags) const { Item::Ptr uriArg = getParamNumber(1,context)->next(context); if(uriArg.isNull()) { return Sequence(context->getMemoryManager()); } const XMLCh *uri = uriArg->asString(context); // on Windows, we can have URIs using \ instead of /; let's normalize them if(uri != 0) { unsigned int len = XPath2Utils::uintStrlen(uri); AutoDeleteArray<XMLCh> newURI(new XMLCh[len + 1]); const XMLCh *src = uri; XMLCh *dst = newURI; while(*src != 0) { if(*src == '\\') *dst = '/'; else *dst = *src; ++src; ++dst; } *dst = 0; uri = context->getMemoryManager()->getPooledString(newURI); } if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionDoc::createSequence"), X("Invalid argument to fn:doc function [err:FODC0005]")); return context->resolveDocument(uri, this, context->getProjection() ? queryPathTree_ : 0); }
static int f_eval_xquery (lf_obj_handle_t ohandle, void *filter_args) { XQQuery *query = ((struct ctx *) filter_args)->query; XQQuery *post_query = ((struct ctx *) filter_args)->post_query; // create context objects AutoDelete<DynamicContext> context(query->createDynamicContext()); AutoDelete<DynamicContext> post_context(post_query->createDynamicContext()); // slurp in the entire object size_t len; const void *data; lf_ref_attr(ohandle, "", &len, &data); // parse the document, set it as context item xercesc::MemBufInputSource input_source((const XMLByte *) data, len, X("diamond")); Node::Ptr doc = context->parseDocument(input_source); context->setContextItem(doc); context->setContextPosition(1); context->setContextSize(1); // execute user query Result result = query->execute(context); // convert into diamond attributes, by executing our "post_query" post_context->setContextItem(result->toSequence(context).first()); post_context->setContextPosition(1); post_context->setContextSize(1); bool settingName = true; char *attributeName = NULL; try { Result post_result = post_query->execute(post_context); Item::Ptr item; while(item = post_result->next(post_context)) { char *str = strdup(UTF8(item->asString(post_context))); if (settingName) { attributeName = strdup(str); } else { //std::cout << "writing attribute '" << attributeName << "':'" << str << "'" << std::endl; lf_write_attr(ohandle, attributeName, strlen(str) + 1, (unsigned char *) str); free(attributeName); } free(str); settingName = !settingName; } } catch(XQException &e) { std::cerr << "XQException: " << UTF8(e.getError()) << std::endl; return 0; } return 1; }
Sequence FunctionConcat::createSequence(DynamicContext* context, int flags) const { XMLBuffer result; for(unsigned int i = 1; i <= getNumArgs(); ++i) { Item::Ptr item = getParamNumber(i,context)->next(context); if(!item.isNull()) { result.append(item->asString(context)); } } return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager()); }
Sequence FunctionCaseFold::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager *memMgr = context->getMemoryManager(); Item::Ptr arg = getParamNumber(1, context)->next(context); if(arg.isNull()) { return Sequence(context->getItemFactory()->createString(XMLUni::fgZeroLenString, context), memMgr); } AutoDeallocate<XMLCh> buf(UnicodeTransformer::caseFold(arg->asString(context), memMgr), memMgr); return Sequence(context->getItemFactory()->createString(buf.get(), context), memMgr); }
bool XQDOMConstructor::getStringValue(const ASTNode *child, XMLBuffer &value, DynamicContext *context) { bool bSomethingFound=false; Result childList = child->createResult(context); Item::Ptr item; bool addSpace = false; while((item = childList->next(context)) != NULLRCP) { if(addSpace) value.append(' '); else addSpace = true; value.append(item->asString(context)); bSomethingFound=true; } return bSomethingFound; }
Sequence FunctionParseXML::createSequence(DynamicContext* context, int flags) const { Item::Ptr item = getParamNumber(1, context)->next(context); if(item.isNull()) return Sequence(context->getMemoryManager()); const XMLCh *xml = item->asString(context); MemBufInputSource src((XMLByte*)xml, XMLString::stringLen(xml) * sizeof(XMLCh), name); src.setEncoding(XMLUni::fgUTF16EncodingString); try { return Sequence(context->parseDocument(src, this, context->getProjection() ? queryPathTree_ : 0), context->getMemoryManager()); } catch(XMLParseException &e) { XQThrow(FunctionException, X("FunctionParseXML::createSequence"), e.getError()); } }
Sequence FunctionStringLength::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager *mm = context->getMemoryManager(); Item::Ptr strParm = getParamNumber(1,context)->next(context); if(strParm.isNull()) return Sequence(context->getItemFactory()->createInteger(0, context), mm); const XMLCh *str = strParm->asString(context); long length = 0; while(*str) { ++length; if(RegxUtil::isHighSurrogate(*str)) ++str; ++str; } return Sequence(context->getItemFactory()->createInteger(length, context), mm); }
const XMLCh *DbXmlDocAvailable::getUriArg(DynamicContext *context) const { const XMLCh *currentUri = 0; Item::Ptr arg = getParamNumber(1, context)->next(context); if(arg != NULLRCP) { // Get the uri argument currentUri = arg->asString(context); } try { context->getItemFactory()-> createAnyURI(currentUri, context); } catch(XQException &) { XQThrow(FunctionException, X("QueryPlanFunction::getUriArg"), X("Invalid URI format [err:FODC0005]")); } return currentUri; }
Sequence FunctionReplace::createSequence(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); const XMLCh* input = XMLUni::fgZeroLenString; Item::Ptr inputString = getParamNumber(1,context)->next(context); if(inputString.notNull()) input = inputString->asString(context); const XMLCh *pattern = getParamNumber(2,context)->next(context)->asString(context); const XMLCh *replacement = getParamNumber(3,context)->next(context)->asString(context); const XMLCh *ptr; for(ptr = replacement; *ptr != chNull; ++ptr) { if(*ptr == chDollarSign) { ++ptr; //check that after the '$' is a digit if(!XMLString::isDigit(*ptr)) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern - '$' without following digit [err:FORX0004]")); } else if(*ptr == chBackSlash) { ++ptr; //check that after the '\' is a '$' or '\' if(*ptr != chDollarSign && *ptr != chBackSlash) { XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern - '\\' without following '$' or '\\' [err:FORX0004]")); } } } const XMLCh *options = XMLUni::fgZeroLenString; if(getNumArgs()>3) options=getParamNumber(4,context)->next(context)->asString(context); //Check that the options are valid - throw an exception if not (can have s,m,i and x) //Note: Are allowed to duplicate the letters. const XMLCh* cursor=options; for(; *cursor != 0; ++cursor){ switch(*cursor) { case chLatin_s: case chLatin_m: case chLatin_i: case chLatin_x: break; default: XQThrow(FunctionException, X("FunctionReplace::createSequence"),X("Invalid regular expression flags [err:FORX0001].")); } } // Now attempt to replace try { AutoDeallocate<const XMLCh> result(replace(input, pattern, replacement, options, memMgr), memMgr); return Sequence(context->getItemFactory()->createString(result.get(), context), memMgr); } catch (ParseException &e){ XMLBuffer buf(1023, memMgr); buf.set(X("Invalid regular expression: ")); buf.append(e.getMessage()); buf.append(X(" [err:FORX0002]")); XQThrow(FunctionException, X("FunctionReplace::createSequence"), buf.getRawBuffer()); } catch (RuntimeException &e){ if(e.getCode()==XMLExcepts::Regex_RepPatMatchesZeroString) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("The pattern matches the zero-length string [err:FORX0003]")); else if(e.getCode()==XMLExcepts::Regex_InvalidRepPattern) XQThrow(FunctionException, X("FunctionReplace::createSequence"), X("Invalid replacement pattern [err:FORX0004]")); else XQThrow(FunctionException, X("FunctionReplace::createSequence"), e.getMessage()); } // Never happens }
Sequence FunctionUnparsedText::createSequence(DynamicContext* context, int flags) const { Item::Ptr uriArg = getParamNumber(1, context)->next(context); if(uriArg.isNull()) { return Sequence(context->getMemoryManager()); } const XMLCh *uri = uriArg->asString(context); if(!XPath2Utils::isValidURI(uri, context->getMemoryManager())) XQThrow(FunctionException, X("FunctionUnparsedText::createSequence"), X("The argument to fn:unparsed-text() is not a valid URI [err:XTDE1170]")); // TBD Implement a URIResolver method for resolving unparsed text - jpcs const XMLCh *baseUri = context->getBaseURI(); InputSource *srcToUse = 0; if(context->getXMLEntityResolver()){ XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, uri, 0, XMLUni::fgZeroLenString, baseUri); srcToUse = context->getXMLEntityResolver()->resolveEntity(&resourceIdentifier); } if(srcToUse == 0) { try { // Resolve the uri against the base uri XMLURL urlTmp; if(baseUri && *baseUri) { urlTmp.setURL(baseUri, uri); } else { urlTmp.setURL(uri); } srcToUse = new URLInputSource(urlTmp); } catch(const MalformedURLException &e) { } } if(srcToUse == 0) { // It's not a URL, so let's assume it's a local file name. if(baseUri && *baseUri) { AutoDeallocate<XMLCh> tmpBuf(XMLPlatformUtils::weavePaths(baseUri, uri), XMLPlatformUtils::fgMemoryManager); srcToUse = new LocalFileInputSource(tmpBuf); } else { srcToUse = new LocalFileInputSource(uri); } } Janitor<InputSource> janIS(srcToUse); if(getNumArgs() == 2) { const XMLCh *encoding = getParamNumber(2, context)->next(context)->asString(context); srcToUse->setEncoding(encoding); } XMLBuffer result; try { BinInputStream *stream = srcToUse->makeStream(); if(stream == NULL) { XMLBuffer buf; buf.set(X("Cannot read unparsed content from ")); buf.append(uri); buf.append(X(" [err:XTDE1170]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } Janitor<BinInputStream> janStream(stream); #ifdef HAVE_GETCONTENTTYPE if(FunctionMatches::matches(stream->getContentType(), X("(text|application)/(xml|[^ +;]+\\+xml)"), X("i"))) { srcToUse->setEncoding(0); srcToUse->setEncoding(FindXMLEncoding().start(*srcToUse, context)); } #endif XPath2Utils::readSource(stream, context->getMemoryManager(), result, srcToUse->getEncoding()); } catch(XMLException &e) { XMLBuffer buf; buf.set(X("Exception reading unparsed content: ")); buf.append(e.getMessage()); buf.append(X(" [err:XTDE1190]")); XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer()); } return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager()); }
QStringList ExternalPlaylist::executeXmlQuery(const QString& filePath, const QString& xPath, const QStringList& parameters){ QStringList results; // initialise Xerces-C and XQilla using XQillaPlatformUtils try{ XQillaPlatformUtils::initialize(); }catch (const xercesc_3_1::XMLException& eXerces){ qDebug("Xerces exception message: %s", UTF8(eXerces.getMessage())); return results; } // get the XQilla DOMImplementation object xercesc_3_1::DOMImplementation *xqillaImplementation = xercesc_3_1::DOMImplementationRegistry::getDOMImplementation(X("XPath2 3.0")); try{ // create a DOMLSParser object AutoDelete<xercesc_3_1::DOMLSParser> parser(xqillaImplementation->createLSParser(xercesc_3_1::DOMImplementationLS::MODE_SYNCHRONOUS, 0)); // disable remote DTD resolution parser->getDomConfig()->setParameter(xercesc_3_1::XMLUni::fgXercesLoadExternalDTD, false); // parse the XML document xercesc_3_1::DOMDocument *document = parser->parseURI(X(filePath.toLocal8Bit().constData())); if(document == 0) throw XQillaException(99,X("No XML document found")); // determine whether to use lightweight query model if(parameters.isEmpty()){ // parse XPath AutoRelease<xercesc_3_1::DOMXPathExpression> expression(document->createExpression(X(xPath.toLocal8Bit().constData()), 0)); // execute query AutoRelease<xercesc_3_1::DOMXPathResult> result(expression->evaluate(document, xercesc_3_1::DOMXPathResult::ITERATOR_RESULT_TYPE, 0)); // iterate over results while(result->iterateNext()) results.push_back(QString::fromUtf8(UTF8(result->getNodeValue()->getTextContent()))); }else{ // set up a simple API query and context to evaluate the parsed document XQilla xqilla; AutoDelete<XQQuery> xQuery(xqilla.parse(X(xPath.toLocal8Bit().constData()))); AutoDelete<DynamicContext> xQueryContext(xQuery->createDynamicContext()); // grab document from xerces API XercesConfiguration xc; Node::Ptr node = xc.createNode(document, xQueryContext.get()); // prepare context if(node && node->isNode()){ xQueryContext->setContextItem(node); xQueryContext->setContextPosition(1); xQueryContext->setContextSize(1); // bind variables for(int i=0; i<(signed)parameters.size(); i += 2){ if(i + 1 >= (signed)parameters.size()) break; Item::Ptr value = xQueryContext->getItemFactory()->createString(X(parameters[i+1].toLocal8Bit().constData()), xQueryContext.get()); xQueryContext->setExternalVariable(X(parameters[i].toLocal8Bit().constData()), value); } } // execute query Result xQueryResults = xQuery->execute(xQueryContext); // iterate over results Item::Ptr item; while(item = xQueryResults->next(xQueryContext)) { results.push_back(QString::fromUtf8(UTF8(item->asString(xQueryContext)))); } } }catch(XQillaException &e){ // DOM3 (xerces) API qDebug("XQillaException: %s", UTF8(e.getString())); }catch(XQException &e){ // Simple API qDebug("XQillaException: %s", UTF8(e.getError())); }catch(...){ qDebug("Unspecified exception with XQilla"); } // Terminate Xerces-C and XQilla using XQillaPlatformUtils XQillaPlatformUtils::terminate(); return results; }