Annotation of parser3/src/types/pa_vxdoc.C, revision 1.40
1.1 parser 1: /** @dom
2: Parser: @b dom parser type.
3:
1.35 misha 4: Copyright(c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
1.11 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 parser 6: */
7: #include "pa_config_includes.h"
8: #ifdef XML
1.14 paf 9:
1.40 ! misha 10: static const char * const IDENT_VXDOC="$Date: 2011-05-18 01:24:47 $";
1.1 parser 11:
12: #include "pa_vxdoc.h"
1.34 misha 13: #include "pa_vbool.h"
1.1 parser 14:
1.39 misha 15: #include "pa_request.h"
16: #include "pa_charset.h"
17:
1.28 paf 18: // defines
19:
20: #define SEARCH_NAMESPACES_NAME "search-namespaces"
21:
1.39 misha 22: #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"
23: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"
24: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"
25: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"
26:
1.30 paf 27:
28: VXnode& VXdoc::wrap(xmlNode& anode) {
29: VXnode* result;
30: if((result=static_cast<VXnode*>(anode._private))) {
31: assert(anode.doc==fdocument);
32: return *result;
33: }
34:
35: result=new VXnode(anode);
36: anode._private=result;
37: anode.doc=fdocument;
38:
39: return *result;
40: }
41:
42:
1.36 misha 43: Value* VXdoc::as(const char* atype) {
1.32 misha 44: return atype && ( strcmp(VXdoc::type(), atype)==0 || strcmp(VXnode::type(), atype)==0 )?this:0;
1.18 paf 45: }
46:
1.34 misha 47: /// VXdoc: true
1.35 misha 48: Value& VXdoc::as_expr_result(bool /*return_string_as_is=false*/) { return VBool::get(as_bool()); }
1.34 misha 49:
1.33 misha 50:
1.2 parser 51: /// VXdoc: $CLASS,$method
1.36 misha 52: Value* VXdoc::get_element(const String& aname) {
1.28 paf 53: if(aname==SEARCH_NAMESPACES_NAME) {
54: return &search_namespaces;
55: }
56:
1.13 paf 57: // up
1.21 paf 58: try {
1.36 misha 59: return VXnode::get_element(aname);
1.24 paf 60: } catch(Exception) {
61: // ignore bad node elements, they can be valid here...
62:
63: // fields
1.31 paf 64: xmlDoc& xmldoc=get_xmldoc();
1.24 paf 65:
66: if(aname=="doctype") {
67: // readonly attribute DocumentType doctype;
1.31 paf 68: if(xmlNode* node=(xmlNode*)xmldoc.intSubset)
69: return &wrap(*node);
70: else
71: return 0;
1.24 paf 72: } else if(aname=="implementation") {
73: // readonly attribute DOMImplementation implementation;
74: return 0;
75: } else if(aname=="documentElement") {
76: // readonly attribute Element documentElement;
1.38 misha 77: xmlNode* rootElement=xmlDocGetRootElement(&xmldoc);
78: return rootElement ? &wrap(*rootElement) : 0;
79: }
1.31 paf 80:
1.25 paf 81: return bark("%s field not found", &aname);
1.24 paf 82: }
1.2 parser 83: }
84:
1.39 misha 85: static int param_option_over_output_option(
86: HashStringValue& param_options, const char* option_name,
87: const String*& output_option) {
88: if(Value* value=param_options.get(String::Body(option_name))){
89: output_option=&value->as_string();
90: return 1;
91: }
92: return 0;
93: }
94: static int param_option_over_output_option(
95: HashStringValue& param_options, const char* option_name,
96: int& output_option) {
97: if(Value* value=param_options.get(String::Body(option_name))) {
98: const String& s=value->as_string();
99: if(s=="yes")
100: output_option=1;
101: else if(s=="no")
102: output_option=0;
103: else
104: throw Exception(PARSER_RUNTIME,
105: &s,
106: "%s must be either 'yes' or 'no'", option_name);
107: return 1;
108: }
109: return 0;
110: }
111:
112: XDocOutputOptions::XDocOutputOptions(Request& r, HashStringValue* options){
113: memset(this, 0, sizeof(*this));
114: indent=standalone=omitXmlDeclaration=-1;
115:
116: /*
117: <xsl:output
118: !method = "xml" | "html" | "text" | qname-but-not-ncname
119: !version = nmtoken
120: !encoding = string
121: !omit-xml-declaration = "yes" | "no"
122: !standalone = "yes" | "no"
123: !doctype-public = string
124: !doctype-system = string
125: cdata-section-elements = qnames
126: !indent = "yes" | "no"
127: !media-type = string />
128: */
129:
130: if(options) {
1.40 ! misha 131: int valid_options=0;
1.39 misha 132: // $.method[xml|html|text]
1.40 ! misha 133: valid_options+=param_option_over_output_option(*options, XDOC_OUTPUT_METHOD_OPTION_NAME, this->method);
1.39 misha 134: // $.version[1.0]
135: valid_options+=param_option_over_output_option(*options, "version", this->version);
136: // $.encoding[windows-1251|...]
137: valid_options+=param_option_over_output_option(*options, "encoding", this->encoding);
138: // $.omit-xml-declaration[yes|no]
139: valid_options+=param_option_over_output_option(*options, "omit-xml-declaration", this->omitXmlDeclaration);
140: // $.standalone[yes|no]
141: valid_options+=param_option_over_output_option(*options, "standalone", this->standalone);
142: // $.indent[yes|no]
143: valid_options+=param_option_over_output_option(*options, "indent", this->indent);
144: // $.media-type[text/{html|xml|plain}]
145: valid_options+=param_option_over_output_option(*options, "media-type", this->mediaType);
146:
147: if(valid_options!=options->count())
148: throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
149: }
150:
151: // default encoding from pool
152: if(!this->encoding)
153: this->encoding=new String(r.charsets.source().NAME(), String::L_TAINTED);
154: // default method=xml
155: if(!this->method)
156: this->method=new String(XDOC_OUTPUT_METHOD_OPTION_VALUE_XML);
157: // default mediaType = depending on method
158: if(!this->mediaType) {
159: if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_XML)
160: this->mediaType=new String("text/xml");
161: else if(*this->method==XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML)
162: this->mediaType=new String("text/html");
163: else // XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT & all others
164: this->mediaType=new String("text/plain");
165: }
166: }
167:
168: // defined at classes/xdoc.C
169: String::C xdoc2buf(Request& r, VXdoc& vdoc,
170: XDocOutputOptions& oo,
171: const String* file_spec,
172: bool use_source_charset_to_render_and_client_charset_to_write_to_header);
173:
174: const String* VXdoc::get_json_string(Json_options* options){
175: XDocOutputOptions xdoc_options_default;
176: String::C buf=xdoc2buf(*options->r, *this, options->xdoc_options ? *options->xdoc_options : xdoc_options_default,
177: 0/*file_name. not to file, to memory*/,
178: true/*use source charset to render, client charset to put to header*/);
179:
180: String& result=*new String("\"", String::L_AS_IS);
181: result << String(buf, String::L_JSON);
182: result << "\"";
183: return &result;
184: }
185:
1.1 parser 186: #endif
E-mail: