root/tags/5.4.pre05/ciupdxslt.c

Revision 1, 7.2 kB (checked in by heitor.barbieri, 4 years ago)

Criação do svn para Cisis.

Line 
1/**
2*  Aplica uma transformacao XSLT de um xml proveniente de um registro Isis e
3*  mostra o resultado da mesma na saida padrao ou arquivo de saida ou ainda em
4*  campo de registro Isis.
5*
6*  Nota: requer que a biblioteca libxslt (The XSLT C library for GNOME) esteja
7*        instalada na maquina.
8*
9*  Uso:  "mx <dbname> proc='Gxslt'"
10*
11*  Formato:
12*             xsl[#<rec_mode>][/<tag>|:<file>][=[@]<xsl_spec>]
13*  onde:
14*           #<rec_mode> - valor 1 ou 2 - indica o formato de saida do registro.
15*           /tag - escreve resultado da transformacao no campo tag do registro.
16*           <file> - escreve resultado da transformacao em arquivo de saida.
17*           [@]<xsl_spec> - especificacao da transformacao. @ le de arquivo.
18*
19**/
20
21#if PROCXSLT
22        //xsl[#<rec_mode>][/<tag>|:<file>][=[@]<xsl_spec>]
23        if (strncmp(p,"xsl", 3) == 0) {
24            extern int xmlLoadExtDtdDefaultValue;
25
26            char *args = p + 3;
27            char *aux = NULL;
28            char *spec = NULL;
29            char *outFile = NULL;
30            char *buffer = NULL;
31            char *buffer2 = NULL;
32            xmlDocPtr doc = NULL;
33            xmlDocPtr res = NULL;
34            xmlDocPtr check = NULL;
35            xmlChar * doc_txt_ptr = NULL;
36            int doc_txt_len = 0;
37            xsltStylesheetPtr stylesheet = NULL;
38            RECSTRU *arecp = NULL;
39            RECSTRU *crecp = NULL;
40            LONGX crec = 0;
41            int tag = 0;
42            int recMode = 1;
43
44            aux = (char *) memchr(args, '=', strlen(args));
45            if (aux != NULL) {
46                spec = aux + 1;
47                *aux = 0;
48            }
49
50            aux = args;
51            if (*aux == '#') {
52                int ch = (int)aux[1];
53
54                recMode = ch - 48;
55                if ((recMode != 1) && (recMode != 2)) {
56                    fatal("fldupdat/procx/Gxsl/rec_mode");
57                }
58                aux += 2;
59            }
60            if (*aux == '/') {
61                tag = atoi(aux + 1);
62                if ((tag <= 0) || (tag > 99999)) {
63                    fatal("fldupdat/procx/Gxsl/tag");
64                }
65            } else if (*aux == ':') {
66                outFile = aux + 1;
67            } else if (*aux != 0) {
68                fatal("fldupdat/procx/Gxsl/parameter");
69            }
70
71            // L�egistro da base
72#if CICPP
73            crecp = new RECSTRU(cisisxp);
74            if (!crecp) fatal("fldupdat/procx/upcrec");
75            crecp->xrecalloc(sizeof(M0STRU));
76            crecp->xrecord(p,0L);
77#else
78            for (crec=maxnrec; crec--; ) {
79                if (!vrecp[crec]) {
80                    break;
81                }
82            }
83            if (crec < 0) {
84                fatal("fldupdat/procx/crec");
85            }
86            recallok(crec,(LONGX)sizeof(M0STRU));
87            record(crec, RECdbxp->dbxname, 0);
88            crecp = vrecp[crec];
89#endif /* CICPP */
90            buffer = malloc(3 * MAXMFRL);
91            if (buffer == NULL) {
92                fatal("fldupdat/procx/Gxsl/xml/malloc/buffer");
93            }
94
95            buffer2 = malloc(MAXMFRL);
96            if (buffer2 == NULL) {
97                fatal("fldupdat/procx/Gxsl/xml/malloc/buffer2");
98            }
99
100            if (recMode == 1) {
101                buffer = dumpRecord1(crecp, recp, buffer, buffer2);
102            } else {
103                buffer = dumpRecord2(crecp, recp, buffer, buffer2);
104            }
105
106            if (spec) {
107                // Le e analisa documento XML de entrada
108                //doc = xmlParseMemory(buffer, strlen(buffer));
109                doc = xmlReadMemory(buffer, 2 * MAXMFRL, NULL, "ISO8859-1",
110                                                          XML_PARSE_NOWARNING);
111                if (doc == NULL) {
112                    fatal("fldupdat/procx/Gxsl/xml/not wellformed");
113                }
114
115                // Le e analisa documento XSLT
116                if (*spec == '@') {
117                    stylesheet =
118                             xsltParseStylesheetFile((const xmlChar *)(spec+1));
119                } else {
120                    xmlDocPtr xsltDoc = xmlReadMemory(spec + 1, strlen(spec + 1),
121                                       NULL, "ISO8859-1", XML_PARSE_NOWARNING);
122                    if (xsltDoc == NULL) {
123                        fatal("fldupdat/procx/Gxsl/xslt/parse");
124                    }
125                    stylesheet = xsltParseStylesheetDoc(xsltDoc);
126                    xmlFreeDoc(xsltDoc);
127                }
128                if (stylesheet == NULL) {
129                    fatal("fldupdat/procx/Gxsl/stylesheet/parse");
130                }
131
132                // Ajusta parametros globais
133                xmlSubstituteEntitiesDefault(1);
134                xmlLoadExtDtdDefaultValue = 1;
135
136                // Processa arquivo
137                if ((stylesheet != NULL) && (doc != NULL)) {
138                    res = xsltApplyStylesheet(stylesheet, doc, NULL);
139                    if (res == NULL) {
140                        fatal("fldupdat/procx/Gxsl/transformation");
141                    }
142                    if (xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len,
143                                               res,  stylesheet) == -1) {
144                        fatal("fldupdat/procx/Gxsl/xml/tostring");
145                    }
146                }
147            } else {/* spec */
148                doc_txt_ptr = strdup(buffer);
149            }
150
151            if (tag > 0) {  // Escreve resultado em registro
152                sprintf(buffer, "h%.5d %.8d %s", tag, strlen(doc_txt_ptr),
153                                                                   doc_txt_ptr);
154#if CICPP
155                if (recp->xfldupdat(buffer)) {
156                    fatal("fldupdat/procx/Gxsl/fldupdat");
157                }
158#else
159                if (fldupdat(irec, buffer)) {
160                    fatal("fldupdat/procx/Gxsl/fldupdat");
161                }
162
163#endif /* CICPP */
164            } else if (outFile) { // Escreve resultado em arquivo
165                int fd = 0;
166                size_t size = strlen(doc_txt_ptr);
167
168                if ((fd = CREAT(outFile, PERMIS)) <= 0) {
169                    fatal("fldupdat/procx/Gxsl/create");
170                }
171                if (CIWRITE(fd, doc_txt_ptr, size) != size) {
172                    fatal("fldupdat/procx/Gxsl/write");
173                }
174                CLOSE(fd);
175            } else {  // Escreve resultado em registro na standard output
176#if CICPP
177                if (recp->xfldupdat("d*")) {
178                    fatal("fldupdat/procx/Gxsl/fldupdat");
179                }
180#else
181                if (fldupdat(irec, "d*")) {
182                    fatal("fldupdat/procx/Gxsl/fldupdat");
183                }
184#endif /* CICPP */
185                printf("%s\n", doc_txt_ptr);
186            }
187
188            // Apaga registro da memoria
189#if CICPP
190            delete crecp;
191#else
192            FREE(vrecp[crec]);
193            vrecp[crec] = NULL;
194            nrecs--;
195#endif /* CICPP */
196
197            // Libera memoria
198            free(buffer);
199            free(buffer2);
200            free(doc_txt_ptr);
201
202            if (spec) {
203                xmlFreeDoc(doc);
204                xmlFreeDoc(res);
205                xmlFreeDoc(check);
206
207                xsltFreeStylesheet(stylesheet);
208                xsltCleanupGlobals();
209                xmlCleanupParser();
210            }
211
212            return NULL;
213        }
214        else
215#endif /* PROCXSLT */
Note: See TracBrowser for help on using the browser.