diff options
Diffstat (limited to 'src/trans.c')
-rw-r--r-- | src/trans.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/src/trans.c b/src/trans.c new file mode 100644 index 0000000..3603436 --- /dev/null +++ b/src/trans.c @@ -0,0 +1,286 @@ +/* $Id: trans.c,v 1.19 2004/11/22 02:28:21 mgrouch Exp $ */ + +#include <config.h> +#include "trans.h" +#include "xmlstar.h" + +/* + * This code is based on xsltproc by Daniel Veillard (daniel@veillard.com) + * (see also http://xmlsoft.org/) + */ + +int errorno = 0; + +/** + * Initialize global command line options + */ +void +xsltInitOptions(xsltOptionsPtr ops) +{ + ops->noval = 1; + ops->nonet = 1; + ops->omit_decl = 0; + ops->show_extensions = 0; + ops->noblanks = 0; + ops->embed = 0; +#ifdef LIBXML_XINCLUDE_ENABLED + ops->xinclude = 0; +#endif +#ifdef LIBXML_HTML_ENABLED + ops->html = 0; +#endif +#ifdef LIBXML_CATALOG_ENABLED + ops->catalogs = 0; +#endif +} + +/** + * Initialize LibXML + */ +void +xsltInitLibXml(xsltOptionsPtr ops) +{ + /* + * Initialize library memory + */ + xmlInitMemory(); + + LIBXML_TEST_VERSION + + /* + * Store line numbers in the document tree + */ + xmlLineNumbersDefault(1); + + /* + * Register the EXSLT extensions + */ + exsltRegisterAll(); + + /* + * Register the test module + */ + xsltRegisterTestModule(); + + if (ops->show_extensions) + { + xsltDebugDumpExtensions(stderr); + exit(EXIT_SUCCESS); + } + + xmlKeepBlanksDefault(1); + if (ops->noblanks) xmlKeepBlanksDefault(0); + xmlPedanticParserDefault(0); + + xmlGetWarningsDefaultValue = 1; + /*xmlDoValidityCheckingDefaultValue = 0;*/ + xmlLoadExtDtdDefaultValue = 1; + + /* + * DTD validation options + */ + if (ops->noval == 0) + { + xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; + } + else + { + xmlLoadExtDtdDefaultValue = 0; + } + +#ifdef LIBXML_XINCLUDE_ENABLED + /* + * enable XInclude + */ + if (ops->xinclude) + xsltSetXIncludeDefault(1); +#endif + +#ifdef LIBXML_CATALOG_ENABLED + /* + * enable SGML catalogs + */ + if (ops->catalogs) + { + char *catalogs = getenv("SGML_CATALOG_FILES"); + if (catalogs == NULL) + fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n"); + else + xmlLoadCatalogs(catalogs); + } +#endif +} + +/* get result of XSL transformation */ +xmlDocPtr +xsltTransform(xsltOptionsPtr ops, xmlDocPtr doc, const char** params, + xsltStylesheetPtr cur, const char *filename) +{ + xsltTransformContextPtr ctxt; + xmlDocPtr res; + + if (ops->omit_decl) + { + cur->omitXmlDeclaration = 1; + } + +#ifdef LIBXML_XINCLUDE_ENABLED + if (ops->xinclude) xmlXIncludeProcess(doc); +#endif + + ctxt = xsltNewTransformContext(cur, doc); + if (ctxt == NULL) return NULL; + + res = xsltApplyStylesheetUser(cur, doc, params, NULL, NULL, ctxt); + + if (ctxt->state == XSLT_STATE_ERROR) + errorno = 9; + if (ctxt->state == XSLT_STATE_STOPPED) + errorno = 10; + xsltFreeTransformContext(ctxt); + xmlFreeDoc(doc); + if (res == NULL) + { + fprintf(stderr, "no result for %s\n", filename); + } + return res; +} + +/** + * Run stylesheet on XML document + */ +void +xsltProcess(xsltOptionsPtr ops, xmlDocPtr doc, const char** params, + xsltStylesheetPtr cur, const char *filename) +{ + xmlDocPtr res = xsltTransform(ops, doc, params, cur, filename); + + if (res && xsltSaveResultToFile(stdout, res, cur) < 0) + { + errorno = EXIT_LIB_ERROR; + } + + xmlFreeDoc(res); +} + +/** + * run XSLT on documents + */ +int xsltRun(xsltOptionsPtr ops, char* xsl, const char** params, + int count, char **docs) +{ + xsltStylesheetPtr cur = NULL; + xmlDocPtr doc, style; + int i, options = 0; + + options = XSLT_PARSE_OPTIONS; + + /* + * Compile XSLT Sylesheet + */ + style = xmlReadFile((const char *) xsl, NULL, options); + if (style == NULL) + { + fprintf(stderr, "cannot parse %s\n", xsl); + cur = NULL; + errorno = 4; + } + else + { + if (ops->embed) + { + cur = xsltLoadStylesheetPI(style); + if (cur != NULL) + { + /* it is an embedded stylesheet */ + xsltProcess(ops, style, params, cur, xsl); + xsltFreeStylesheet(cur); + cur = NULL; + } + for (i=0; i<count; i++) + { + style = xmlReadFile((const char *) docs[i], NULL, options); + if (style == NULL) + { + fprintf(stderr, "cannot parse %s\n", docs[i]); + cur = NULL; + goto done; + } + cur = xsltLoadStylesheetPI(style); + if (cur != NULL) + { + /* it is an embedded stylesheet */ + xsltProcess(ops, style, params, cur, docs[i]); + xsltFreeStylesheet(cur); + cur = NULL; + } + } + goto done; + } + + cur = xsltParseStylesheetDoc(style); + if (cur != NULL) + { + if (cur->errors != 0) + { + errorno = 5; + goto done; + } + if (cur->indent == 1) xmlIndentTreeOutput = 1; + else xmlIndentTreeOutput = 0; + } + else + { + xmlFreeDoc(style); + errorno = 5; + goto done; + } + } + + /* + * run XSLT + */ + if ((cur != NULL) && (cur->errors == 0)) + { + for (i=0; i<count; i++) + { + doc = NULL; +#ifdef LIBXML_HTML_ENABLED + if (ops->html) doc = htmlReadFile(docs[i], NULL, options); + else +#endif + { + doc = xmlReadFile((const char *) docs[i], NULL, options); + } + + if (doc == NULL) + { + fprintf(stderr, "unable to parse %s\n", docs[i]); + errorno = 6; + continue; + } + xsltProcess(ops, doc, params, cur, docs[i]); + } + + if (count == 0) + { + /* stdin */ + doc = NULL; +#ifdef LIBXML_HTML_ENABLED + if (ops->html) doc = htmlParseFile("-", NULL); + else +#endif + doc = xmlReadFile("-", NULL, options); + xsltProcess(ops, doc, params, cur, "-"); + } + } + +done: + + /* + * Clean up + */ + if (cur != NULL) xsltFreeStylesheet(cur); + + return(errorno); +} |