/* Wrapper for xsltApplyStylesheet */ xmlDocPtr mxslt_doc_xml_apply_stylesheet(mxslt_doc_t * mxslt_doc, xsltStylesheetPtr style, xmlDocPtr doc, const char ** params) { xmlDocPtr retval; xsltTransformContextPtr userCtxt; userCtxt=xsltNewTransformContext(style, doc); if(userCtxt == NULL) return NULL; xsltSetCtxtParseOptions(userCtxt, MXSLT_XSLT_OPTIONS); /* XXX I don't like this much :| ... I consider this an hack */ /* userCtxt->_private=(void *)mxslt_doc; */ userCtxt->outputFile=mxslt_doc->localfile; #ifndef MXSLT_DISABLE_EXTENSIONS xsltRegisterExtElement(userCtxt, (xmlChar *)"header-set", (xmlChar *)MXSLT_NS_URI, mxslt_transform_header); xsltRegisterExtElement(userCtxt, (xmlChar *)"value-of", (xmlChar *)MXSLT_NS_URI, mxslt_transform_value_of); xsltRegisterExtElement(userCtxt, (xmlChar *)"header-set", (xmlChar *)MXSLT_OBSOLETE_NS_URI, mxslt_transform_header); xsltRegisterExtElement(userCtxt, (xmlChar *)"value-of", (xmlChar *)MXSLT_OBSOLETE_NS_URI, mxslt_transform_value_of); #endif retval=xsltApplyStylesheetUser(style, doc, params, NULL, NULL, userCtxt); xsltFreeTransformContext(userCtxt); return retval; }
QString XSLTransformer::transform(const QString &xml, QHash<QString, QString> const ¶ms) const { // Read XML data intro an xmlDoc. QByteArray xmlData(xml.toUtf8()); QScopedPointer<xmlDoc, XmlDocDeleter> doc( xmlReadMemory(xmlData.constData(), xmlData.size(), 0, 0, 0)); if (!doc) throw std::runtime_error("XSLTransformer::transform: Could not open XML data"); // Hmpf, data conversions. char const **cParams = new char const *[params.size() * 2 + 1]; int i = 0; for (QHash<QString, QString>::const_iterator iter = params.constBegin(); iter != params.constEnd(); ++iter) { QByteArray keyData(iter.key().toUtf8()); QByteArray valueData(iter.value().toUtf8()); char const *cKey = strdup(keyData.constData()); char const *cValue = strdup(valueData.constData()); cParams[i] = cKey; cParams[i + 1] = cValue; i += 2; } cParams[params.size() * 2] = 0; // Terminator QScopedPointer<xsltTransformContext, XsltTransformContextDeleter> ctx( xsltNewTransformContext(d_xslPtr.data(), doc.data())); xsltSetCtxtParseOptions(ctx.data(), XSLT_PARSE_OPTIONS); // Transform... QScopedPointer<xmlDoc, XmlDocDeleter> res( xsltApplyStylesheetUser(d_xslPtr.data(), doc.data(), cParams, NULL, NULL, ctx.data())); if (!res) throw std::runtime_error("XSLTransformer::transform: Could not apply transformation!"); else if (ctx->state != XSLT_STATE_OK) throw std::runtime_error("XSLTransformer::transform: Transformation error, check your query!"); xmlChar *outputBare = 0; int outputLen = -1; xsltSaveResultToString(&outputBare, &outputLen, res.data(), d_xslPtr.data()); QScopedPointer<xmlChar, XmlDeleter> output(outputBare); if (!output) throw std::runtime_error("Could not apply stylesheet!"); QString result(QString::fromUtf8(reinterpret_cast<char const *>(output.data()))); // Deallocate parameter memory for (int i = 0; i < params.size() * 2; ++i) free(const_cast<char *>(cParams[i])); delete[] cParams; return result; }
bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String& resultString, String& resultEncoding) { RefPtr<Document> ownerDocument = sourceNode->document(); setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->docLoader()); xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get()); if (!sheet) { setXSLTLoadCallBack(0, 0, 0); return false; } m_stylesheet->clearDocuments(); xmlChar* origMethod = sheet->method; if (!origMethod && mimeType == "text/html") sheet->method = (xmlChar*)"html"; bool success = false; bool shouldFreeSourceDoc = false; if (xmlDocPtr sourceDoc = xmlDocPtrFromNode(sourceNode, shouldFreeSourceDoc)) { // The XML declaration would prevent parsing the result as a fragment, and it's not needed even for documents, // as the result of this function is always immediately parsed. sheet->omitXmlDeclaration = true; xsltTransformContextPtr transformContext = xsltNewTransformContext(sheet, sourceDoc); registerXSLTExtensions(transformContext); // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor <xsl:sort> algorithm only compares by code point. xsltSetCtxtSortFunc(transformContext, xsltUnicodeSortFunction); // This is a workaround for a bug in libxslt. // The bug has been fixed in version 1.1.13, so once we ship that this can be removed. if (!transformContext->globalVars) transformContext->globalVars = xmlHashCreate(20); const char** params = xsltParamArrayFromParameterMap(m_parameters); xsltQuoteUserParams(transformContext, params); xmlDocPtr resultDoc = xsltApplyStylesheetUser(sheet, sourceDoc, 0, 0, 0, transformContext); xsltFreeTransformContext(transformContext); freeXsltParamArray(params); if (shouldFreeSourceDoc) xmlFreeDoc(sourceDoc); if ((success = saveResultToString(resultDoc, sheet, resultString))) { mimeType = resultMIMEType(resultDoc, sheet); resultEncoding = (char*)resultDoc->encoding; } xmlFreeDoc(resultDoc); } sheet->method = origMethod; setXSLTLoadCallBack(0, 0, 0); xsltFreeStylesheet(sheet); m_stylesheet = 0; return success; }
static VXdoc& _transform(Request& r, const String* stylesheet_source, VXdoc& vdoc, xsltStylesheetPtr stylesheet, const xmlChar** transform_params) { xmlDoc& xmldoc=vdoc.get_xmldoc(); xsltTransformContext_auto_ptr transformContext( xsltNewTransformContext(stylesheet, &xmldoc)); // make params literal if (transformContext->globalVars == NULL) // strangly not initialized by xsltNewTransformContext transformContext->globalVars = xmlHashCreate(20); xsltQuoteUserParams(transformContext.get(), (const char**)transform_params); // do transform xmlDoc *transformed=xsltApplyStylesheetUser( stylesheet, &xmldoc, 0/*already quoted-inserted transform_params*/, 0/*const char* output*/, 0/*FILE *profile*/, transformContext.get()); if(!transformed || xmlHaveGenericErrors()) throw XmlException(stylesheet_source, r); //gdome_xml_doc_mkref dislikes XML_HTML_DOCUMENT_NODE type, fixing transformed->type=XML_DOCUMENT_NODE; // constructing result VXdoc& result=*new VXdoc(r.charsets, *transformed); /* grabbing options <xsl:output !method = "xml" | "html" | "text" X| qname-but-not-ncname !version = nmtoken !encoding = string !omit-xml-declaration = "yes" | "no" !standalone = "yes" | "no" !doctype-public = string !doctype-system = string Xcdata-section-elements = qnames !indent = "yes" | "no" !media-type = string /> */ XDocOutputOptions& oo=result.output_options; oo.method=stylesheet->method?&r.transcode(stylesheet->method):0; oo.encoding=stylesheet->encoding?&r.transcode(stylesheet->encoding):0; oo.mediaType=stylesheet->mediaType?&r.transcode(stylesheet->mediaType):0; oo.indent=stylesheet->indent; oo.version=stylesheet->version?&r.transcode(stylesheet->version):0; oo.standalone=stylesheet->standalone; oo.omitXmlDeclaration=stylesheet->omitXmlDeclaration; // return return result; }
void yelp_transform_start (YelpTransform *transform, xmlDocPtr document, gchar **params) { transform->inputDoc = document; transform->context = xsltNewTransformContext (transform->stylesheet, transform->inputDoc); if (!transform->context) { YelpError *error = yelp_error_new (_("Broken Transformation"), _("An unknown error occurred while attempting to " "transform the document.")); transform_set_error (transform, error); return; } transform->params = g_strdupv (params); transform->context->_private = transform; if (!exslt_registered) { exsltRegisterAll (); exslt_registered = TRUE; } xsltRegisterExtElement (transform->context, BAD_CAST "document", BAD_CAST YELP_NAMESPACE, (xsltTransformFunction) xslt_yelp_document); xsltRegisterExtElement (transform->context, BAD_CAST "cache", BAD_CAST YELP_NAMESPACE, (xsltTransformFunction) xslt_yelp_cache); xsltRegisterExtFunction (transform->context, BAD_CAST "input", BAD_CAST YELP_NAMESPACE, (xmlXPathFunction) xslt_yelp_input); transform->mutex = g_mutex_new (); g_mutex_lock (transform->mutex); transform->running = TRUE; transform->thread = g_thread_create ((GThreadFunc) transform_run, transform, FALSE, NULL); g_mutex_unlock (transform->mutex); }
static int create_xslt_parser( struct xslt_info *info, xmlNodePtr node, const xmlChar *str ) { if(!node) return 1; info->sheet = xsltNewStylesheet(); if (!info->sheet) return 0; info->ctxt = xsltNewTransformContext( info->sheet, node->doc ); if (!info->ctxt) return 0; info->pattern = xsltCompilePattern( str, node->doc, node, info->sheet, info->ctxt ); if (!info->pattern) return 0; return 1; }
// Processes input XML file (e.g., instance metadata) into output XML file or string (e.g., for libvirt) // using XSL-T specification file (e.g., libvirt.xsl) static int apply_xslt_stylesheet (const char * xsltStylesheetPath, const char * inputXmlPath, const char * outputXmlPath, char * outputXmlBuffer, int outputXmlBufferSize) { int err = OK; INIT(); xsltStylesheetPtr cur = xsltParseStylesheetFile ((const xmlChar *)xsltStylesheetPath); if (cur) { xmlDocPtr doc = xmlParseFile (inputXmlPath); if (doc) { xsltTransformContextPtr ctxt = xsltNewTransformContext (cur, doc); // need context to get result xsltSetCtxtParseOptions (ctxt, 0); // TODO: do we want any XSL-T parsing options? xmlDocPtr res = xsltApplyStylesheetUser (cur, doc, NULL, NULL, NULL, ctxt); // applies XSLT to XML int applied_ok = ctxt->state==XSLT_STATE_OK; // errors are communicated via ctxt->state xsltFreeTransformContext (ctxt); if (res && applied_ok) { // save to a file, if path was provied if (outputXmlPath!=NULL) { FILE * fp = fopen (outputXmlPath, "w"); if (fp) { int bytes = xsltSaveResultToFile (fp, res, cur); if (bytes==-1) { logprintfl (EUCAERROR, "ERROR: failed to save XML document to %s\n", outputXmlPath); err = ERROR; } fclose (fp); } else { logprintfl (EUCAERROR, "ERROR: failed to create file %s\n", outputXmlPath); err = ERROR; } } // convert to an ASCII buffer, if such was provided if (err==OK && outputXmlBuffer!=NULL && outputXmlBufferSize > 0) { xmlChar * buf; int buf_size; if (xsltSaveResultToString (&buf, &buf_size, res, cur)==0) { // success if (buf_size < outputXmlBufferSize) { bzero (outputXmlBuffer, outputXmlBufferSize); for (int i=0, j=0; i<buf_size; i++) { char c = (char) buf [i]; if (c != '\n') // remove newlines outputXmlBuffer [j++] = c; } } else { logprintfl (EUCAERROR, "ERROR: XML string buffer is too small (%d > %d)\n", buf_size, outputXmlBufferSize); err = ERROR; } xmlFree (buf); } else { logprintfl (EUCAERROR, "ERROR: failed to save XML document to a string\n"); err = ERROR; } } } else { logprintfl (EUCAERROR, "ERROR: failed to apply stylesheet %s to %s\n", xsltStylesheetPath, inputXmlPath); err = ERROR; } if (res!=NULL) xmlFreeDoc(res); xmlFreeDoc(doc); } else { logprintfl (EUCAERROR, "ERROR: failed to parse XML document %s\n", inputXmlPath); err = ERROR; } xsltFreeStylesheet(cur); } else { logprintfl (EUCAERROR, "ERROR: failed to open and parse XSL-T stylesheet file %s\n", xsltStylesheetPath); err = ERROR; } return err; }
static ngx_buf_t * ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx) { int len, rc, doc_type; u_char *type, *encoding; ngx_buf_t *b; ngx_uint_t i; xmlChar *buf; xmlDocPtr doc, res; ngx_http_xslt_sheet_t *sheet; ngx_http_xslt_filter_loc_conf_t *conf; conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); sheet = conf->sheets.elts; doc = ctx->doc; /* preallocate array for 4 params */ if (ngx_array_init(&ctx->params, r->pool, 4 * 2 + 1, sizeof(char *)) != NGX_OK) { xmlFreeDoc(doc); return NULL; } for (i = 0; i < conf->sheets.nelts; i++) { ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc); if (ctx->transform == NULL) { xmlFreeDoc(doc); return NULL; } if (conf->params && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK) { xsltFreeTransformContext(ctx->transform); xmlFreeDoc(doc); return NULL; } if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) { xsltFreeTransformContext(ctx->transform); xmlFreeDoc(doc); return NULL; } res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc, ctx->params.elts, NULL, NULL, ctx->transform); xsltFreeTransformContext(ctx->transform); xmlFreeDoc(doc); if (res == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xsltApplyStylesheet() failed"); return NULL; } doc = res; /* reset array elements */ ctx->params.nelts = 0; } /* there must be at least one stylesheet */ if (r == r->main) { type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet); } else { type = NULL; } encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet); doc_type = doc->type; ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "xslt filter type: %d t:%s e:%s", doc_type, type ? type : (u_char *) "(null)", encoding ? encoding : (u_char *) "(null)"); rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet); xmlFreeDoc(doc); if (rc != 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xsltSaveResultToString() failed"); return NULL; } if (len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "xsltSaveResultToString() returned zero-length result"); return NULL; } b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { ngx_free(buf); return NULL; } b->pos = buf; b->last = buf + len; b->memory = 1; if (encoding) { r->headers_out.charset.len = ngx_strlen(encoding); r->headers_out.charset.data = encoding; } if (r != r->main) { return b; } b->last_buf = 1; if (type) { len = ngx_strlen(type); r->headers_out.content_type_len = len; r->headers_out.content_type.len = len; r->headers_out.content_type.data = type; } else if (doc_type == XML_HTML_DOCUMENT_NODE) { r->headers_out.content_type_len = sizeof("text/html") - 1; ngx_str_set(&r->headers_out.content_type, "text/html"); } r->headers_out.content_type_lowcase = NULL; return b; }
static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp) /* {{{ */ { xmlDocPtr newdocp = NULL; xmlDocPtr doc = NULL; xmlNodePtr node = NULL; xsltTransformContextPtr ctxt; php_libxml_node_object *object; char **params = NULL; int clone; zval *doXInclude, member, rv; zend_object_handlers *std_hnd; FILE *f; int secPrefsError = 0; int secPrefsValue; xsltSecurityPrefsPtr secPrefs = NULL; node = php_libxml_import_node(docp); if (node) { doc = node->doc; } if (doc == NULL) { php_error_docref(NULL, E_WARNING, "Invalid Document"); return NULL; } if (style == NULL) { php_error_docref(NULL, E_WARNING, "No stylesheet associated to this object"); return NULL; } if (intern->profiling) { if (php_check_open_basedir(intern->profiling)) { f = NULL; } else { f = VCWD_FOPEN(intern->profiling, "w"); } } else { f = NULL; } if (intern->parameter) { params = php_xsl_xslt_make_params(intern->parameter, 0); } intern->doc = emalloc(sizeof(php_libxml_node_object)); memset(intern->doc, 0, sizeof(php_libxml_node_object)); if (intern->hasKeys == 1) { doc = xmlCopyDoc(doc, 1); } else { object = Z_LIBXML_NODE_P(docp); intern->doc->document = object->document; } php_libxml_increment_doc_ref(intern->doc, doc); ctxt = xsltNewTransformContext(style, doc); ctxt->_private = (void *) intern; std_hnd = zend_get_std_object_handlers(); ZVAL_STRING(&member, "doXInclude"); doXInclude = std_hnd->read_property(id, &member, BP_VAR_IS, NULL, &rv); if (Z_TYPE_P(doXInclude) != IS_NULL) { convert_to_long(doXInclude); ctxt->xinclude = Z_LVAL_P(doXInclude); } zval_ptr_dtor(&member); secPrefsValue = intern->securityPrefs; /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */ if (secPrefsValue != XSL_SECPREF_NONE) { secPrefs = xsltNewSecurityPrefs(); if (secPrefsValue & XSL_SECPREF_READ_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { secPrefsError = 1; } } if (secPrefsError == 1) { php_error_docref(NULL, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons"); } else { newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt); } if (f) { fclose(f); } xsltFreeTransformContext(ctxt); if (secPrefs) { xsltFreeSecurityPrefs(secPrefs); } if (intern->node_list != NULL) { zend_hash_destroy(intern->node_list); FREE_HASHTABLE(intern->node_list); intern->node_list = NULL; } php_libxml_decrement_doc_ref(intern->doc); efree(intern->doc); intern->doc = NULL; if (params) { clone = 0; while(params[clone]) { efree(params[clone++]); } efree(params); } return newdocp; }
<xsl:template match=\"text()[(following-sibling::* or preceding-sibling::*) and normalize-space(.) != '']\"> \ <sg_wrap><xsl:value-of select=\".\" /></sg_wrap> \ </xsl:template> \ <xsl:template match=\"@*|node()\"> \ <xsl:copy> \ <xsl:apply-templates select=\"@*|node()\"/> \ </xsl:copy> \ </xsl:template> \ </xsl:stylesheet>"; xmlParserCtxtPtr ctxt = xmlNewParserCtxt(); xmlDocPtr xml = xmlCtxtReadMemory(ctxt, sheet, strlen(sheet), NULL, NULL, 0); span_wrap_sheet = xsltParseStylesheetDoc(xml); } xsltTransformContextPtr ctxt = xsltNewTransformContext(span_wrap_sheet, doc); xmlSetGenericErrorFunc(ctxt, parsleyXsltError); xmlDocPtr out = xsltApplyStylesheetUser(span_wrap_sheet, doc, NULL, NULL, NULL, ctxt); xsltFreeTransformContext(ctxt); return out; } void _parsley_set_user_agent(char *agent) { if (parsley_user_agent_header != NULL) { free(parsley_user_agent_header); } if (agent == NULL) {
xmlDocPtr c_XSLTProcessor::apply_stylesheet() { SYNC_VM_REGS_SCOPED(); if (m_stylesheet == nullptr || m_doc == nullptr) { raise_error("Unable to apply stylesheet"); return nullptr; } xsltTransformContextPtr ctxt = xsltNewTransformContext (m_stylesheet, m_doc); if (ctxt == nullptr) { raise_error("Unable to apply stylesheet"); return nullptr; } ctxt->_private = this; xsltSecurityPrefsPtr prefs = nullptr; if (m_secprefs != k_XSL_SECPREF_NONE) { prefs = xsltNewSecurityPrefs(); int error = 0; if (m_secprefs & k_XSL_SECPREF_READ_FILE) { if (xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid) != 0) { error = 1; } } if (m_secprefs & k_XSL_SECPREF_WRITE_FILE) { if (xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid) != 0) { error = 1; } } if (m_secprefs & k_XSL_SECPREF_CREATE_DIRECTORY) { if (xsltSetSecurityPrefs(prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid) != 0) { error = 1; } } if (m_secprefs & k_XSL_SECPREF_READ_NETWORK) { if (xsltSetSecurityPrefs(prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid) != 0) { error = 1; } } if (m_secprefs & k_XSL_SECPREF_WRITE_NETWORK) { if (xsltSetSecurityPrefs(prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid) != 0) { error = 1; } } if (xsltSetCtxtSecurityPrefs(prefs, ctxt) != 0) { error = 1; } if (error == 1) { raise_error("Can't set libxslt security properties, not doing " "transformation for security reasons"); return nullptr; } } xsltRegisterExtFunction(ctxt, (const xmlChar*) "functionString", (const xmlChar*) "http://php.net/xsl", xslt_ext_function_string_php ); xsltRegisterExtFunction(ctxt, (const xmlChar*) "function", (const xmlChar*) "http://php.net/xsl", xslt_ext_function_object_php ); for (ArrayIter iter(m_params); iter; ++iter) { assert(iter.first().isString()); assert(iter.second().isString()); xmlChar *value = xslt_string_to_xpathexpr(iter.second().toString().c_str()); if (value) { xsltEvalOneUserParam(ctxt, (const xmlChar*)iter.first().toString().c_str(), (const xmlChar*)value ); xmlFree(value); } } FILE *profile = nullptr; if (m_profile) { profile = fopen(m_profile.data(), "w"); } xmlDocPtr res = xsltApplyStylesheetUser(m_stylesheet, m_doc, nullptr, nullptr, profile, ctxt); if (profile) { fclose(profile); } xsltFreeTransformContext(ctxt); if (prefs) { xsltFreeSecurityPrefs(prefs); } return res; }
static void transform_run (YelpTransform *transform) { YelpTransformPrivate *priv = GET_PRIV (transform); debug_print (DB_FUNCTION, "entering\n"); priv->stylesheet = xsltParseStylesheetFile (BAD_CAST (priv->stylesheet_file)); if (priv->stylesheet == NULL) { g_mutex_lock (&priv->mutex); if (priv->error) g_error_free (priv->error); priv->error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING, _("The XSLT stylesheet ‘%s’ is either missing or not valid."), priv->stylesheet_file); g_object_ref (transform); g_idle_add ((GSourceFunc) transform_error, transform); g_mutex_unlock (&priv->mutex); return; } priv->context = xsltNewTransformContext (priv->stylesheet, priv->input); if (priv->context == NULL) { g_mutex_lock (&priv->mutex); if (priv->error) g_error_free (priv->error); priv->error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING, _("The XSLT stylesheet ‘%s’ is either missing or not valid."), priv->stylesheet_file); g_object_ref (transform); g_idle_add ((GSourceFunc) transform_error, transform); g_mutex_unlock (&priv->mutex); return; } priv->context->_private = transform; xsltRegisterExtElement (priv->context, BAD_CAST "document", BAD_CAST YELP_NAMESPACE, (xsltTransformFunction) xslt_yelp_document); xsltRegisterExtElement (priv->context, BAD_CAST "cache", BAD_CAST YELP_NAMESPACE, (xsltTransformFunction) xslt_yelp_cache); xsltRegisterExtFunction (priv->context, BAD_CAST "input", BAD_CAST YELP_NAMESPACE, (xmlXPathFunction) xslt_yelp_aux); priv->output = xsltApplyStylesheetUser (priv->stylesheet, priv->input, (const char **) priv->params, NULL, NULL, priv->context); g_mutex_lock (&priv->mutex); priv->running = FALSE; if (!priv->cancelled) { g_idle_add ((GSourceFunc) transform_final, transform); g_mutex_unlock (&priv->mutex); } else { g_mutex_unlock (&priv->mutex); g_object_unref (transform); } }