예제 #1
0
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;
}
예제 #2
0
파일: xdoc.C 프로젝트: viatsko/parser3
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;
}