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; }