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