summaryrefslogtreecommitdiff
path: root/src/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/trans.c')
-rw-r--r--src/trans.c286
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);
+}