/******************************************************************************* 14.9.2 fn:parse-xml-fragment ********************************************************************************/ bool FnParseXmlFragmentIterator::nextImpl( store::Item_t& result, PlanState& planState) const { zstring docString; FnParseXmlFragmentIteratorState* state; DEFAULT_STACK_INIT(FnParseXmlFragmentIteratorState, state, planState); if (consumeNext(result, theChildren[0].getp(), planState)) { if (result->isStreamable()) { state->theFragmentStream.theStream = &result->getStream(); } else { result->getStringValue2(docString); state->theFragmentStream.theIss = new std::istringstream(docString.c_str()); state->theFragmentStream.theStream = state->theFragmentStream.theIss; } state->theProperties.setBaseUri(theSctx->get_base_uri()); state->theProperties.setParseExternalParsedEntity(true); state->theProperties.setStoreDocument(false); state->baseUri = state->theProperties.getBaseUri(); // create only one document node holding all fragment nodes state->theFragmentStream.only_one_doc_node = 1; try { result = GENV.getStore().loadDocument(state->baseUri, state->docUri, state->theFragmentStream, state->theProperties); } catch ( ZorbaException const &e ) { if ( !state->theProperties.getNoError() ) { XQueryException xe( XQUERY_EXCEPTION(err::FODC0006, ERROR_PARAMS( "fn:parse-xml-fragment()", e.what() ), ERROR_LOC( loc ))); set_data( xe, e ); throw xe; } result = nullptr; } if (result != NULL) STACK_PUSH(true, state); } // if STACK_END(state); }
/******************************************************************************* 14.9.1.1 fn-zorba-xml:canonicalize ********************************************************************************/ bool FnZorbaCanonicalizeIterator::nextImpl(store::Item_t& result, PlanState& planState) const { zstring lDocString; xmlDocPtr lDoc; xmlChar* lResult; std::istream* lInstream = NULL; char buf[1024]; store::Item_t tempItem; FnZorbaCanonicalizeIteratorState* state; DEFAULT_STACK_INIT(FnZorbaCanonicalizeIteratorState, state, planState); // Read the XML string // if the XML string is a streamable string it will have to be materialized // since the libxml2 xmlReadMemory functions can't work with streamable strings consumeNext(result, theChildren[0].getp(), planState); // read options if (theChildren.size() == 2) { consumeNext(tempItem, theChildren[1].getp(), planState); zorba::processOptions(tempItem, state->theProperties, theSctx, loc); } try { if (result->isStreamable()) { lInstream = &result->getStream(); while (lInstream->good()) { lInstream->read(buf, 1024); lDocString.append(buf, static_cast<zstring::size_type>(lInstream->gcount())); } } else { result->getStringValue2(lDocString); } int lOptions = XML_PARSE_NOERROR | state->theProperties.toLibXmlOptions(); lDoc = xmlReadMemory(lDocString.c_str(), lDocString.size(), "input.xml", NULL, lOptions); if (!lDoc) { zstring lErrorMsg; lErrorMsg = "\"" + lDocString + "\""; throw XQUERY_EXCEPTION(err::FOCZ0001, ERROR_PARAMS("x:canonicalize()", lErrorMsg ), ERROR_LOC(loc)); } xmlC14NDocDumpMemory(lDoc, NULL, 2/*XML_C14N_1_1*/, NULL, 1, &lResult); lDocString = zstring((char*)lResult); xmlFree(lResult); xmlFreeDoc(lDoc); } catch ( std::exception const& ) { zstring lErrorMsg; lErrorMsg = "\"" + lDocString + "\""; throw XQUERY_EXCEPTION(err::FOCZ0001, ERROR_PARAMS("x:canonicalize()", lErrorMsg ), ERROR_LOC(loc)); } STACK_PUSH(GENV_ITEMFACTORY->createString(result, lDocString), state); STACK_END(state); }
bool FnZorbaParseXmlFragmentIterator::nextImpl( store::Item_t& result, PlanState& planState) const { store::Store& lStore = GENV.getStore(); zstring docString; store::Item_t tempItem; bool validated = true; FnZorbaParseXmlFragmentIteratorState* state; DEFAULT_STACK_INIT(FnZorbaParseXmlFragmentIteratorState, state, planState); if (consumeNext(result, theChildren[0].getp(), planState)) { if (result->isStreamable()) { state->theFragmentStream.theStream = &result->getStream(); state->theFragmentStream.setStreamReleaser(result->getStreamReleaser()); result->setStreamReleaser(nullptr); } else { result->getStringValue2(docString); state->theFragmentStream.theIss = new std::istringstream(docString.c_str()); state->theFragmentStream.theStream = state->theFragmentStream.theIss; } // read options consumeNext(tempItem, theChildren[1].getp(), planState); state->theProperties.setBaseUri(theSctx->get_base_uri()); state->theProperties.setStoreDocument(false); state->theProperties.setUseCachedDocument(false); processOptions(tempItem, state->theProperties, theSctx, loc); state->theProperties.setCreateDocParentLink(false); // baseURI serves both as the base URI used by the XML parser // to resolve relative entity references within the document, // and as the base URI of the document node that is returned. state->baseUri = state->theProperties.getBaseUri(); state->docUri = state->theProperties.getBaseUri(); //////////////////////////////////////////////////////////////////////// // External parsed entity processing //////////////////////////////////////////////////////////////////////// if (state->theProperties.getParseExternalParsedEntity()) { state->theFragmentStream.root_elements_to_skip = state->theProperties.getSkipRootNodes(); while ( ! state->theFragmentStream.stream_is_consumed()) { try { result = lStore.loadDocument(state->baseUri, state->docUri, state->theFragmentStream, state->theProperties); } catch ( ZorbaException const &e ) { if ( !state->theProperties.getNoError() ) { XQueryException xe( XQUERY_EXCEPTION( err::FODC0006, ERROR_PARAMS( "parse-xml:parse()", e.what() ), ERROR_LOC( loc ) ) ); set_data( xe, e ); throw xe; } result = nullptr; } if (result == NULL) continue; // Return the children of document node state->theFragmentStream.children = result->getChildren(); while (state->theFragmentStream.children->next(result) && result != NULL) { if (state->theProperties.getSkipTopLevelTextNodes() && result->getNodeKind() == store::StoreConsts::textNode) continue; STACK_PUSH(true, state); } } } //////////////////////////////////////////////////////////////////////// // XML document processing //////////////////////////////////////////////////////////////////////// else // if (!state->theProperties.getEnableExtParsedEntity()) { try { result = lStore.loadDocument(state->baseUri, state->docUri, *state->theFragmentStream.theStream, state->theProperties); } catch ( ZorbaException const &e ) { if ( !state->theProperties.getNoError() ) { XQueryException xe( XQUERY_EXCEPTION( err::FODC0006, ERROR_PARAMS( "parse-xml:parse()", e.what() ), ERROR_LOC( loc ) ) ); set_data( xe, e ); throw xe; } result = nullptr; } if (result != NULL) { #ifndef ZORBA_NO_XMLSCHEMA if (state->theProperties.getSchemaLaxValidate() || state->theProperties.getSchemaStrictValidate()) { try { tempItem = NULL; // used as the effectiveValidationValue()'s typeName validated = Validator::effectiveValidationValue( result, result, tempItem, theSctx->get_typemanager(), state->theProperties.getSchemaLaxValidate() ? ParseConstants::val_lax : ParseConstants::val_strict, theSctx, this->loc); } catch (ZorbaException& /*e*/) { if ( ! state->theProperties.getNoError()) throw; else { result = NULL; validated = false; } } } #endif // Ignore the schema validation options if Zorba is built without schema support STACK_PUSH(validated, state); } // if (result != NULL) } // if (state->theProperties.getEnableExtParsedEntity()) } // if (consumeNext(result, theChildren[0].getp(), planState)) STACK_END(state); }