Annotation of parser3/src/classes/xdoc.C, revision 1.60
1.1 parser 1: /** @file
1.2 parser 2: Parser: @b xdoc parser class.
1.1 parser 3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.43 paf 5: Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.1 parser 6:
1.60 ! paf 7: $Id: xdoc.C,v 1.59 2002/01/14 17:48:56 paf Exp $
1.1 parser 8: */
1.30 parser 9: #include "pa_types.h"
1.1 parser 10: #ifdef XML
11:
1.59 paf 12: #include "pa_stylesheet_connection.h"
13: #include "classes.h"
1.1 parser 14: #include "pa_request.h"
15: #include "pa_vxdoc.h"
1.53 paf 16: #include "pa_charset.h"
1.1 parser 17: #include "pa_vfile.h"
18: #include "xnode.h"
19:
1.59 paf 20: extern "C" {
21: #include "gdomecore/gdome-xml-node.h"
22: #include "gdomecore/gdome-xml-document.h"
23: };
24: #include "libxslt/transform.h"
25:
1.1 parser 26: // defines
27:
28: #define XDOC_CLASS_NAME "xdoc"
29:
30: #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"
31: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"
32: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"
33: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"
34: #define XDOC_OUTPUT_DEFAULT_INDENT 4
35:
36: // class
37:
38: class MXdoc : public MXnode {
39: public: // VStateless_class
1.54 paf 40: Value *create_new_value(Pool& pool) { return new(pool) VXdoc(pool, 0); }
1.1 parser 41:
42: public:
43: MXdoc(Pool& pool);
44:
45: public: // Methoded
46: bool used_directly() { return true; }
1.5 parser 47: void configure_admin(Request& r);
1.1 parser 48: };
49:
50: // methods
51:
1.54 paf 52: static void writeNode(Request& r, const String& method_name, GdomeNode *node,
53: GdomeException exc) {
54: if(!node || exc)
55: throw Exception(0, 0,
56: &method_name,
57: exc);
58:
59: Pool& pool=r.pool();
60:
61: // write out result
62: VXnode& result=*new(pool) VXnode(pool, node);
63: r.write_no_lang(result);
64: }
65:
1.16 parser 66: // Element createElement(in DOMString tagName) raises(DOMException);
67: static void _createElement(Request& r, const String& method_name, MethodParams *params) {
68: Pool& pool=r.pool();
69: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
70:
1.39 paf 71: const String& tagName=params->as_string(0, "tagName must be string");
1.16 parser 72:
1.54 paf 73: GdomeException exc;
74: GdomeNode *node=
75: (GdomeNode *)gdome_doc_createElement(vdoc.get_document(&method_name),
1.57 paf 76: pool.transcode(tagName).get(),
1.54 paf 77: &exc);
78: writeNode(r, method_name, node, exc);
1.16 parser 79: }
80:
81: // DocumentFragment createDocumentFragment()
1.26 parser 82: static void _createDocumentFragment(Request& r, const String& method_name, MethodParams *) {
1.16 parser 83: Pool& pool=r.pool();
84: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
85:
1.54 paf 86: GdomeException exc;
87: GdomeNode *node=
88: (GdomeNode *)gdome_doc_createDocumentFragment(
89: vdoc.get_document(&method_name),
90: &exc);
91: writeNode(r, method_name, node, exc);
1.16 parser 92: }
93:
94: // Text createTextNode(in DOMString data);
95: static void _createTextNode(Request& r, const String& method_name, MethodParams *params) {
96: Pool& pool=r.pool();
97: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
98:
1.40 paf 99: const String& data=params->as_string(0, "data must be string");
1.16 parser 100:
1.54 paf 101: GdomeException exc;
102: GdomeNode *node=(GdomeNode *)gdome_doc_createTextNode(
103: vdoc.get_document(&method_name),
1.57 paf 104: pool.transcode(data).get(),
1.54 paf 105: &exc);
106: writeNode(r, method_name, node, exc);
1.16 parser 107: }
108:
109: // Comment createComment(in DOMString data)
110: static void _createComment(Request& r, const String& method_name, MethodParams *params) {
111: Pool& pool=r.pool();
112: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
113:
1.26 parser 114: const String& data=params->as_string(0, "data must be string");
1.16 parser 115:
1.54 paf 116: GdomeException exc;
117: GdomeNode *node=(GdomeNode *)gdome_doc_createComment(
118: vdoc.get_document(&method_name),
1.57 paf 119: pool.transcode(data).get(),
1.54 paf 120: &exc);
121: writeNode(r, method_name, node, exc);
1.16 parser 122: }
123:
124: // CDATASection createCDATASection(in DOMString data) raises(DOMException);
125: static void _createCDATASection(Request& r, const String& method_name, MethodParams *params) {
126: Pool& pool=r.pool();
127: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
128:
1.26 parser 129: const String& data=params->as_string(0, "data must be string");
1.16 parser 130:
1.54 paf 131: GdomeException exc;
132: GdomeNode *node=(GdomeNode *)gdome_doc_createCDATASection(
133: vdoc.get_document(&method_name),
1.57 paf 134: pool.transcode(data).get(),
1.54 paf 135: &exc);
136: writeNode(r, method_name, node, exc);
1.16 parser 137: }
138:
139: // ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data) raises(DOMException);
140: static void _createProcessingInstruction(Request& r, const String& method_name, MethodParams *params) {
141: Pool& pool=r.pool();
142: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
143:
1.26 parser 144: const String& target=params->as_string(0, "data must be string");
145: const String& data=params->as_string(1, "data must be string");
1.16 parser 146:
1.54 paf 147: GdomeException exc;
148: GdomeNode *node=(GdomeNode *)gdome_doc_createProcessingInstruction(
149: vdoc.get_document(&method_name),
1.57 paf 150: pool.transcode(target).get(),
151: pool.transcode(data).get(),
1.54 paf 152: &exc);
153: writeNode(r, method_name, node, exc);
1.16 parser 154: }
155:
156: // Attr createAttribute(in DOMString name) raises(DOMException);
157: static void _createAttribute(Request& r, const String& method_name, MethodParams *params) {
158: Pool& pool=r.pool();
159: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
160:
1.26 parser 161: const String& name=params->as_string(0, "name must be string");
1.16 parser 162:
1.54 paf 163: GdomeException exc;
164: GdomeNode *node=(GdomeNode *)gdome_doc_createAttribute(
165: vdoc.get_document(&method_name),
1.57 paf 166: pool.transcode(name).get(),
1.54 paf 167: &exc);
168: writeNode(r, method_name, node, exc);
1.16 parser 169: }
170: // EntityReference createEntityReference(in DOMString name) raises(DOMException);
171: static void _createEntityReference(Request& r, const String& method_name, MethodParams *params) {
172: Pool& pool=r.pool();
173: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
174:
1.26 parser 175: const String& name=params->as_string(0, "name must be string");
1.16 parser 176:
1.54 paf 177: GdomeException exc;
178: GdomeNode *node=(GdomeNode *)gdome_doc_createEntityReference(
179: vdoc.get_document(&method_name),
1.57 paf 180: pool.transcode(name).get(),
1.54 paf 181: &exc);
182: writeNode(r, method_name, node, exc);
1.16 parser 183: }
184:
185: static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) {
186: Pool& pool=r.pool();
187: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
188:
1.54 paf 189: const String& name=params->as_string(0, "name must be string");
1.16 parser 190:
1.54 paf 191: GdomeException exc;
1.16 parser 192: VHash& result=*new(pool) VHash(pool);
1.54 paf 193: if(GdomeNodeList *nodes=
194: gdome_doc_getElementsByTagName(
195: vdoc.get_document(&method_name),
1.57 paf 196: pool.transcode(name).get(),
1.54 paf 197: &exc)) {
198: gulong length=gdome_nl_length(nodes, &exc);
199: for(gulong i=0; i<length; i++) {
1.16 parser 200: String& skey=*new(pool) String(pool);
201: {
202: char *buf=(char *)pool.malloc(MAX_NUMBER);
203: snprintf(buf, MAX_NUMBER, "%d", i);
204: skey << buf;
205: }
206:
1.54 paf 207: result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc)));
1.16 parser 208: }
209: }
210:
211: // write out result
212: r.write_no_lang(result);
213: }
214:
215: static void _getElementsByTagNameNS(Request& r, const String& method_name, MethodParams *params) {
216: Pool& pool=r.pool();
217: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
218:
219: // namespaceURI;localName
1.54 paf 220: const String& namespaceURI=params->as_string(0, "namespaceURI must be string");
221: const String& localName=params->as_string(0, "localName must be string");
1.16 parser 222:
1.54 paf 223: GdomeException exc;
1.16 parser 224: VHash& result=*new(pool) VHash(pool);
1.54 paf 225: if(GdomeNodeList *nodes=
226: gdome_doc_getElementsByTagNameNS(
227: vdoc.get_document(&method_name),
1.57 paf 228: pool.transcode(namespaceURI).get(),
229: pool.transcode(localName).get(),
1.54 paf 230: &exc)) {
231: gulong length=gdome_nl_length(nodes, &exc);
232: for(gulong i=0; i<length; i++) {
1.16 parser 233: String& skey=*new(pool) String(pool);
234: {
235: char *buf=(char *)pool.malloc(MAX_NUMBER);
236: snprintf(buf, MAX_NUMBER, "%d", i);
237: skey << buf;
238: }
239:
1.54 paf 240: result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc)));
1.16 parser 241: }
242: }
243:
1.54 paf 244:
1.16 parser 245: // write out result
246: r.write_no_lang(result);
247: }
248:
1.54 paf 249: static void _getElementById(Request& r, const String& method_name, MethodParams *params) {
250: Pool& pool=r.pool();
251: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.16 parser 252:
1.54 paf 253: // elementId
254: const String& elementId=params->as_string(0, "elementID must be string");
1.1 parser 255:
1.54 paf 256: GdomeException exc;
257: if(GdomeNode *node=(GdomeNode *)gdome_doc_getElementById(
258: vdoc.get_document(&method_name),
1.57 paf 259: pool.transcode(elementId).get(),
1.54 paf 260: &exc)) {
261: // write out result
262: VXnode& result=*new(pool) VXnode(pool, node);
263: r.write_no_lang(result);
264: } else if(exc)
265: throw Exception(0, 0,
266: &method_name,
267: exc);
268: }
269: /*
270: GdomeNode *gdome_doc_importNode (GdomeDocument *self, GdomeNode *importedNode, GdomeBoolean deep, GdomeException *exc);
271: GdomeElement *gdome_doc_createElementNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);
272: GdomeAttr *gdome_doc_createAttributeNS (GdomeDocument *self, GdomeDOMString *namespaceURI, GdomeDOMString *qualifiedName, GdomeException *exc);
273: */
1.1 parser 274:
275:
1.54 paf 276: static void _create(Request& r, const String& method_name, MethodParams *params) {
277: //_asm int 3;
278: Pool& pool=r.pool();
279: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 280:
1.54 paf 281: const String& qualifiedName=params->as_string(0, "qualifiedName must be string");
1.1 parser 282:
1.54 paf 283: GdomeException exc;
284: /*
285: GdomeDocumentType *documentType=gdome_di_createDocumentType (
286: docimpl,
287: pool.transcode(qualifiedName),
288: 0/*publicId* /,
289: 0/*systemId* /,
290: &exc);
291: if(!documentType || exc)
292: throw Exception(0, 0,
293: &method_name,
294: exc);
295: */
296: GdomeDocument *document=gdome_di_createDocument (domimpl,
297: 0/*namespaceURI*/,
1.57 paf 298: pool.transcode(qualifiedName).get(),
1.54 paf 299: 0/*doctype*/,
300: &exc);
301: if(!document || exc)
302: throw Exception(0, 0,
303: &method_name,
304: exc);
1.1 parser 305:
1.57 paf 306: /// +xalan createXMLDecl ?
1.9 parser 307:
1.54 paf 308: // replace any previous parsed source
309: vdoc.set_document(document);
310: }
1.9 parser 311:
1.56 paf 312: /// @test xmlSAXParseMemory(NULL<<error handler subst, buffer, size, 0)
1.54 paf 313: static void _set(Request& r, const String& method_name, MethodParams *params) {
314: // _asm int 3;
315: Pool& pool=r.pool();
316: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.9 parser 317:
1.54 paf 318: Value& vxml=params->as_junction(0, "xml must be code");
319: Temp_lang temp_lang(r, String::UL_XML);
320: const String& xml=r.process(vxml).as_string();
1.9 parser 321:
1.54 paf 322: GdomeException exc;
323: GdomeDocument *document=gdome_di_createDocFromMemory(domimpl,
324: xml.cstr(String::UL_UNSPECIFIED, r.connection),
1.55 paf 325: GDOME_LOAD_PARSING
326: /* GDOME_LOAD_VALIDATING */
1.54 paf 327: /*|GDOME_LOAD_SUBSTITUTE_ENTITIES */,
328: &exc);
329: if(!document || exc)
330: throw Exception(0, 0,
331: &method_name,
332: exc);
1.9 parser 333:
1.54 paf 334: // replace any previous parsed source
335: vdoc.set_document(document);
1.9 parser 336: }
337:
1.54 paf 338: static void _load(Request& r, const String& method_name, MethodParams *params) {
339: Pool& pool=r.pool();
340: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.9 parser 341:
1.54 paf 342: // filespec
343: const String& file_name=params->as_string(0, "uri must be string");
344: const String& uri=r.absolute(file_name);
345:
346: GdomeException exc;
347: GdomeDocument *document=gdome_di_createDocFromURI(domimpl,
348: uri.cstr(),
1.55 paf 349: GDOME_LOAD_PARSING
350: /*GDOME_LOAD_VALIDATING */
1.54 paf 351: /*|GDOME_LOAD_SUBSTITUTE_ENTITIES */,
352: &exc);
353: if(!document || exc)
354: throw Exception(0, 0,
355: &method_name,
356: exc);
1.9 parser 357:
1.54 paf 358: // replace any previous parsed source
359: vdoc.set_document(document);
1.9 parser 360: }
361:
1.54 paf 362: /*
1.46 paf 363: static void param_option_over_output_option(Pool& pool,
364: Hash *param_options, const char *option_name,
365: XalanDOMString& output_option) {
366: if(Value *value=static_cast<Value *>(param_options->get(*new(pool)
367: String(pool, option_name)))) {
368: output_option.clear();
369: output_option.append(value->as_string().cstr());
370: }
371: }
372: static void param_option_over_output_option(Pool& pool,
373: Hash *param_options, const char *option_name,
374: bool& output_option) {
375: if(Value *value=static_cast<Value *>(param_options->get(*new(pool)
376: String(pool, option_name)))) {
377: const String& s=value->as_string();
378: if(s=="yes")
379: output_option=true;
380: else if(s=="no")
381: output_option=false;
382: else
383: throw Exception(0, 0,
384: &s,
385: "%s must be either 'yes' or 'no'", option_name);
386: }
387: }
388:
1.54 paf 389: static std::auto_ptr<FormatterListener> create_optioned_listener(
1.46 paf 390: Pool& pool, const String& method_name, MethodParams *params, int index,
1.52 paf 391: VXdoc::Output_options& oo, Writer& writer) {
1.46 paf 392: /*
393: XalanDOMString encoding;
394: XalanDOMString mediaType;
395: XalanDOMString doctypeSystem;
396: XalanDOMString doctypePublic;
397: bool doIndent;
398: XalanDOMString version;
399: XalanDOMString standalone;
400: bool xmlDecl;
1.54 paf 401: * /
1.9 parser 402:
1.46 paf 403: /*
404: <xsl:output
405: !method = "xml" | "html" | "text" | qname-but-not-ncname
406: !version = nmtoken
407: !encoding = string
408: !omit-xml-declaration = "yes" | "no"
409: !standalone = "yes" | "no"
410: !doctype-public = string
411: !doctype-system = string
412: cdata-section-elements = qnames
413: !indent = "yes" | "no"
414: !media-type = string />
1.54 paf 415: * /
1.9 parser 416:
1.46 paf 417: /*
418: fToXML->setStripCData(stripCData);
419: fToXML->setEscapeCData(escapeCData);
1.54 paf 420: * /
1.1 parser 421:
1.46 paf 422: // configuring with options from parameter...
1.1 parser 423: if(params->size()>index) {
1.20 parser 424: Value& voptions=params->as_no_junction(index, "options must be string");
1.1 parser 425: if(voptions.is_defined()) {
1.34 parser 426: if(Hash *options=voptions.get_hash(&method_name)) {
1.1 parser 427: // $.method[xml|html|text]
428: if(Value *vmethod=static_cast<Value *>(options->get(*new(pool)
429: String(pool, XDOC_OUTPUT_METHOD_OPTION_NAME))))
1.46 paf 430: oo.method=vmethod->as_string().cstr();
1.1 parser 431:
1.46 paf 432: // $.version[1.0]
433: param_option_over_output_option(pool, options, "version", oo.version);
1.1 parser 434: // $.encoding[windows-1251|...]
1.46 paf 435: param_option_over_output_option(pool, options, "encoding", oo.encoding);
436: // $.omit-xml-declaration[yes|no]
437: bool omit_xml_declaration=!oo.xmlDecl;
438: param_option_over_output_option(pool, options, "omit-xml-declaration", omit_xml_declaration);
439: oo.xmlDecl=!omit_xml_declaration;
440: // $.standalone[yes|no]
441: param_option_over_output_option(pool, options, "standalone", oo.standalone);
442: // $.doctype-public[?]
443: param_option_over_output_option(pool, options, "doctype-public", oo.doctypePublic);
444: // $.doctype-system[?]
445: param_option_over_output_option(pool, options, "doctype-system", oo.doctypeSystem);
446: // $.indent[yes|no]
447: param_option_over_output_option(pool, options, "indent", oo.doIndent);
448: // $.media-type[text/{html|xml|plain}]
449: param_option_over_output_option(pool, options, "media-type", oo.mediaType);
1.19 parser 450: }
1.1 parser 451: }
452: }
453:
1.46 paf 454: // default encoding from pool
455: if(oo.encoding.empty())
1.53 paf 456: oo.encoding.append(pool.get_source_charset().name().cstr());
1.46 paf 457: // default method=xml
458: if(!oo.method)
459: oo.method=XDOC_OUTPUT_METHOD_OPTION_VALUE_XML;
460:
461: if(strcmp(oo.method, XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)==0) {
462: if(oo.mediaType.empty())
463: oo.mediaType.append("text/xml");
1.52 paf 464: return std::auto_ptr<FormatterListener>(new FormatterToXML(writer,
1.46 paf 465: oo.version,
466: oo.doIndent,
1.1 parser 467: XDOC_OUTPUT_DEFAULT_INDENT, // indent
1.46 paf 468: oo.encoding,
469: oo.mediaType,
470: oo.doctypeSystem,
471: oo.doctypePublic,
472: oo.xmlDecl,
473: oo.standalone
1.49 paf 474: ));
1.46 paf 475: } else if(strcmp(oo.method, XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)==0) {
476: if(oo.mediaType.empty())
477: oo.mediaType.append("text/html");
1.52 paf 478: return std::auto_ptr<FormatterListener>(new FormatterToHTML(writer,
1.46 paf 479: oo.encoding,
480: oo.mediaType,
481: oo.doctypeSystem,
482: oo.doctypePublic,
483: oo.doIndent,
484: XDOC_OUTPUT_DEFAULT_INDENT, // indent
485: oo.version,
486: oo.standalone,
487: oo.xmlDecl
1.49 paf 488: ));
1.46 paf 489: } else if(strcmp(oo.method, XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT)==0) {
490: if(oo.mediaType.empty())
491: oo.mediaType.append("text/plain");
1.52 paf 492: return std::auto_ptr<FormatterListener>(new FormatterToText(writer,
1.46 paf 493: oo.encoding
1.49 paf 494: ));
1.1 parser 495: } else
1.29 parser 496: throw Exception(0, 0,
1.46 paf 497: &method_name,
1.1 parser 498: XDOC_OUTPUT_METHOD_OPTION_NAME " option is invalid; valid methods are: "
499: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "', "
500: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "', "
501: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "'");
1.52 paf 502:
503: // never reached
1.1 parser 504: }
1.54 paf 505: */
1.1 parser 506:
507: static void _save(Request& r, const String& method_name, MethodParams *params) {
508: Pool& pool=r.pool();
1.46 paf 509: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 510:
1.20 parser 511: const String& file_name=params->as_string(0, "file name must be string");
1.54 paf 512: const String& filespec=r.absolute(file_name);
1.1 parser 513:
1.54 paf 514: GdomeException exc;
515: if(!gdome_di_saveDocToFile(domimpl,
516: vdoc.get_document(&method_name),
517: filespec.cstr(String::UL_FILE_SPEC),
518: GDOME_SAVE_LIBXML_INDENT /*GDOME_SAVE_STANDARD */,
519: &exc))
520: throw Exception(0, 0,
521: &method_name,
522: exc);
1.1 parser 523: }
524:
525: static void _string(Request& r, const String& method_name, MethodParams *params) {
526: Pool& pool=r.pool();
1.21 parser 527: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 528:
1.54 paf 529: char *mem;
530: GdomeException exc;
531: if(!gdome_di_saveDocToMemory(domimpl,
532: vdoc.get_document(&method_name),
533: &mem,
534: GDOME_SAVE_LIBXML_INDENT /*GDOME_SAVE_STANDARD */,
535: &exc))
536: throw Exception(0, 0,
537: &method_name,
538: exc);
539:
540: // move to pool memory
1.58 paf 541: size_t buf_size=strlen(mem);
542: char *buf=(char *)pool.malloc(buf_size);
543: memcpy(buf, mem, buf_size);
1.54 paf 544: g_free(mem);
545: // write out result
1.58 paf 546: r.write_no_lang(*new(pool) String(pool, buf, buf_size));
1.1 parser 547: }
548:
1.58 paf 549: /// @test remove text/xml const. <output method+mediatype / ^file[method+mediatype
1.1 parser 550: static void _file(Request& r, const String& method_name, MethodParams *params) {
551: Pool& pool=r.pool();
1.46 paf 552: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 553:
1.58 paf 554: char *mem;
555: GdomeException exc;
556: if(!gdome_di_saveDocToMemory(domimpl,
557: vdoc.get_document(&method_name),
558: &mem,
559: GDOME_SAVE_LIBXML_INDENT /*GDOME_SAVE_STANDARD */,
560: &exc))
561: throw Exception(0, 0,
562: &method_name,
563: exc);
1.1 parser 564:
1.58 paf 565: // move to pool memory
566: size_t buf_size=strlen(mem);
567: char *buf=(char *)pool.malloc(buf_size);
568: memcpy(buf, mem, buf_size);
569: g_free(mem);
1.1 parser 570:
1.58 paf 571: // write out result
572: VFile& vfile=*new(pool) VFile(pool);
573: const String& scontent_type=*new(pool) String(pool, "text/xml");
574: Value *vcontent_type=new(pool) VString(scontent_type);
575: VHash *vhcontent_type=new(pool) VHash(pool);
576: vhcontent_type->hash(&method_name).put(*value_name, new(pool) VString(scontent_type));
577: const String& scharset=pool.get_source_charset().name();
578: vhcontent_type->hash(&method_name).put(*new(pool) String(pool, "charset"), new(pool) VString(scharset));
579: vcontent_type=vhcontent_type;
580:
581: vfile.set(false/*tainted*/, buf, buf_size, 0/*file_name*/, vcontent_type);
582: r.write_no_lang(vfile);
1.1 parser 583: }
1.58 paf 584:
1.38 paf 585: /// @test lang=String::UL_UNSPECIFIED?
1.1 parser 586: static void add_xslt_param(const Hash::Key& aattribute, Hash::Val *ameaning,
587: void *info) {
1.59 paf 588: Value *meaning=static_cast<Value *>(ameaning);
589: Pool& pool=meaning->pool();
590: const char **transform_params=(const char **)info;
591: *transform_params++=pool.transcode(aattribute)->str;
592: *transform_params++=pool.transcode(meaning->as_string())->str;
1.1 parser 593: }
1.24 parser 594: static void _transform(Request& r, const String& method_name, MethodParams *params) {
1.59 paf 595: //_asm int 3;
1.24 parser 596: Pool& pool=r.pool();
597: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
598:
599: // params
1.59 paf 600: const char **transform_params=0;
1.24 parser 601: if(params->size()>1) {
1.59 paf 602: Value& vparams=params->as_no_junction(1, "transform parameters must be hash");
1.24 parser 603: if(vparams.is_defined())
1.59 paf 604: if(Hash *params=vparams.get_hash(&method_name)) {
605: transform_params=
606: (const char **)pool.malloc(sizeof(const char *)*params->size()*2+1);
607: params->for_each(add_xslt_param, transform_params);
608: transform_params[params->size()*2]=0;
609: } else
1.29 parser 610: throw Exception(0, 0,
1.24 parser 611: &method_name,
612: "transform parameters parameter must be hash");
613: }
614:
615: // stylesheet
1.59 paf 616: const String& stylesheet_filespec=r.absolute(params->as_string(0, "file name must be string"));
1.32 parser 617: Stylesheet_connection& connection=stylesheet_manager->get_connection(stylesheet_filespec);
1.24 parser 618:
619: // transform
1.59 paf 620: xsltStylesheet *stylesheet=connection.stylesheet(false/*nocache*/);
621: xmlDoc *document=((Gdome_xml_Document*)vdoc.get_document(&method_name))->n;
622: xsltTransformContext *transformContext=xsltNewTransformContext(stylesheet, document);
623: xmlDoc *transformed=xsltApplyStylesheetUser(
624: stylesheet,
625: document,
626: transform_params,
627: 0/*const char *output*/,
628: 0/*FILE *profile*/,
629: transformContext);
630: if(!transformed) {
631: // close
1.13 parser 632: connection.close();
1.59 paf 633: throw Exception(0, 0,
634: &method_name,
635: "transform failed. TODO: show errors");
1.13 parser 636: }
1.42 paf 637:
1.59 paf 638: //gdome_xml_doc_mkref: invalid node type
639: transformed->type=XML_DOCUMENT_NODE; //XML_HTML_DOCUMENT_NODE actuall
640: // constructing result
641: GdomeDocument *gdomeDocument=gdome_xml_doc_mkref(transformed);
642: if(!gdomeDocument)
643: throw Exception(0, 0,
644: &method_name,
645: "gdome_xml_doc_mkref failed");
646: VXdoc& result=*new(pool) VXdoc(pool, gdomeDocument);
647: // grabbing <output> options
648: /*
649: <xsl:output
650: !method = "xml" | "html" | "text"
651: X| qname-but-not-ncname
652: !version = nmtoken
653: !encoding = string
654: !omit-xml-declaration = "yes" | "no"
655: !standalone = "yes" | "no"
656: !doctype-public = string
657: !doctype-system = string
658: cdata-section-elements = qnames
659: !indent = "yes" | "no"
660: !media-type = string />
661: */
662: memset(&result.output_options, 0, sizeof(result.output_options));
663: VXdoc::Output_options& oo=result.output_options;
664:
1.60 ! paf 665: oo.method=stylesheet->method?&pool.transcode(stylesheet->method):0;
! 666: oo.encoding=stylesheet->encoding?&pool.transcode(stylesheet->encoding):0;
! 667: oo.mediaType=stylesheet->mediaType?&pool.transcode(stylesheet->mediaType):0;
! 668: oo.doctypeSystem=stylesheet->doctypeSystem?&pool.transcode(stylesheet->doctypeSystem):0;
! 669: oo.doctypePublic=stylesheet->doctypePublic?&pool.transcode(stylesheet->doctypePublic):0;
1.59 paf 670: oo.indent=stylesheet->indent!=0;
1.60 ! paf 671: oo.version=stylesheet->version?&pool.transcode(stylesheet->version):0;
1.59 paf 672: oo.standalone=stylesheet->standalone!=0;
673: oo.omitXmlDeclaration=stylesheet->omitXmlDeclaration!=0;
674:
675: xsltFreeTransformContext(transformContext);
1.42 paf 676: // close
677: connection.close();
1.59 paf 678:
679: // exceptions now allowed
680:
681: // check method
682: if(oo.method && (
683: *oo.method!=XDOC_OUTPUT_METHOD_OPTION_VALUE_XML
684: || *oo.method!=XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML
685: || *oo.method!=XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT))
686: throw Exception(0, 0,
687: &method_name,
688: "unsupported output method specified");
689:
690: // write out result
691: r.write_no_lang(result);
692:
1.1 parser 693: }
694:
1.16 parser 695: // constructor
1.2 parser 696:
1.16 parser 697: MXdoc::MXdoc(Pool& apool) : MXnode(apool) {
698: set_name(*NEW String(pool(), XDOC_CLASS_NAME));
1.2 parser 699:
1.16 parser 700: /// @test how to create empty type html?
1.2 parser 701:
1.16 parser 702: /// DOM1
1.2 parser 703:
1.16 parser 704: // Element createElement(in DOMString tagName) raises(DOMException);
705: add_native_method("createElement", Method::CT_DYNAMIC, _createElement, 1, 1);
706: // DocumentFragment createDocumentFragment();
707: add_native_method("createDocumentFragment", Method::CT_DYNAMIC, _createDocumentFragment, 0, 0);
708: // Text createTextNode(in DOMString data);
709: add_native_method("createTextNode", Method::CT_DYNAMIC, _createTextNode, 1, 1);
710: // Comment createComment(in DOMString data);
711: add_native_method("createComment", Method::CT_DYNAMIC, _createComment, 1, 1);
712: // CDATASection createCDATASection(in DOMString data) raises(DOMException);
713: add_native_method("createCDATASection", Method::CT_DYNAMIC, _createCDATASection, 1, 1);
714: // ProcessingInstruction createProcessingInstruction(in DOMString target, in DOMString data) raises(DOMException);
715: add_native_method("createProcessingInstruction", Method::CT_DYNAMIC, _createProcessingInstruction, 2, 2);
716: // Attr createAttribute(in DOMString name) raises(DOMException);
717: add_native_method("createAttribute", Method::CT_DYNAMIC, _createAttribute, 1, 1);
718: // EntityReference createEntityReference(in DOMString name) raises(DOMException);
719: add_native_method("createEntityReference", Method::CT_DYNAMIC, _createEntityReference, 1, 1);
720: // NodeList getElementsByTagName(in DOMString tagname);
1.54 paf 721: add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
722: // ^xdoc.getElementsByTagNameNS[namespaceURI;localName] = array of nodes
723: add_native_method("getElementsByTagNameNS", Method::CT_DYNAMIC, _getElementsByTagNameNS, 2, 2);
1.2 parser 724:
1.16 parser 725: /// DOM2(?)
1.2 parser 726:
1.16 parser 727: // ^xdoc.getElementById[elementId]
728: add_native_method("getElementById", Method::CT_DYNAMIC, _getElementById, 1, 1);
1.1 parser 729:
1.16 parser 730: /// parser
731:
1.54 paf 732: // ^xdoc::create{qualifiedName}
733: add_native_method("create", Method::CT_DYNAMIC, _create, 1, 1);
734: // ^xdoc::set[<some>xml</some>]
735: add_native_method("set", Method::CT_DYNAMIC, _set, 1, 1);
736:
737: // ^xdoc::load[some.xml]
738: add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
739:
1.2 parser 740: // ^xdoc.save[some.xml]
741: // ^xdoc.save[some.xml;options hash]
1.1 parser 742: add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2);
743:
1.2 parser 744: // ^xdoc.string[] <doc/>
745: // ^xdoc.string[options hash] <doc/>
1.1 parser 746: add_native_method("string", Method::CT_DYNAMIC, _string, 0, 1);
747:
1.2 parser 748: // ^xdoc.file[] file with "<doc/>"
749: // ^xdoc.file[options hash] file with "<doc/>"
1.58 paf 750: add_native_method("file", Method::CT_DYNAMIC, _file, 0, 1);
1.1 parser 751:
1.8 parser 752: // ^xdoc.transform[stylesheet file_name]
753: // ^xdoc.transform[stylesheet file_name;params hash]
1.59 paf 754: add_native_method("transform", Method::CT_DYNAMIC, _transform, 1, 2);
1.2 parser 755:
1.1 parser 756: }
1.5 parser 757:
758: void MXdoc::configure_admin(Request& r) {
759: }
760:
1.1 parser 761: // global variable
762:
763: Methoded *Xdoc_class;
764:
765: // creator
766:
767: #endif
768:
769: Methoded *MXdoc_create(Pool& pool) {
770: return
771: #ifdef XML
1.33 parser 772: Xdoc_class=new(pool) MXdoc(pool)
1.1 parser 773: #else
774: 0
775: #endif
776: ;
777: }
E-mail: