Exemplo n.º 1
0
QString XSLTransformer::transform(const QString &xml, QHash<QString, QString> const &params) 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;
}
Exemplo n.º 2
0
  /* 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;
}
Exemplo n.º 3
0
// 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;
}