54 #include <libxslt/xslt.h>
55 #include <libxslt/xsltInternals.h>
56 #include <libxslt/transform.h>
57 #include <libxslt/xsltutils.h>
58 #include <libxslt/extensions.h>
59 #include <libxml/xpath.h>
60 #include <libxml/xpathInternals.h>
81 if (ss->method ==
NULL)
83 return strcmp(
reinterpret_cast<const char *
>(ss->method),
89 if (ss->_private ==
NULL)
90 xsltFreeStylesheet(ss);
96 xsltFreeStylesheet(ss);
102 xsltStylesheetPtr ss,
105 xmlChar * xml_string;
106 int xml_string_length;
108 if (xsltSaveResultToString(&xml_string,
109 &xml_string_length, doc, ss) >= 0)
112 if (xml_string_length)
113 s.assign(helper.
get(), xml_string_length);
119 xsltStylesheetPtr ss,
120 const char * filename,
123 return xsltSaveResultToFilename(filename, doc, ss, 0) >= 0;
131 for (std::vector<xmlNodePtr>::const_iterator k =
nodes_to_free_.begin();
143 xmlXPathParserContext * ctxt =
144 reinterpret_cast<xmlXPathParserContext *
>(c);
145 xsltTransformContextPtr xslt_ctxt =
146 xsltXPathGetTransformContext(ctxt);
149 xslt_ctxt->_private);
150 xmlNodePtr current_node = ctxt->context->node;
151 xmlDocPtr current_doc = ctxt->context->doc;
155 key.first =
reinterpret_cast<const char *
>(ctxt->context->function);
156 if (ctxt->context->functionURI !=
NULL)
157 key.second =
reinterpret_cast<const char *
>(
158 ctxt->context->functionURI);
166 std::vector<xslt::xpath_object> args;
172 args.reserve(arg_num);
173 for (
int k = 0; k < arg_num; ++k) {
174 xmlXPathObjectPtr current_arg = valuePop(ctxt);
176 args.insert(args.begin(),
178 args[0].set_from_xslt();
190 found->second.first->pimpl_->xpath_parser_ctxt = ctxt;
194 found->second.first->execute(args, node, doc);
195 }
catch (
const std::exception & ex) {
198 found->second.first->report_error(
error.c_str());
201 "extension function '" +
key.first +
"'");
202 found->second.first->report_error(
error.c_str());
206 found->second.first->pimpl_->xpath_parser_ctxt =
NULL;
213 void *instruction_node_,
214 void *compiled_stylesheet_info)
216 xsltTransformContextPtr xslt_ctxt =
217 reinterpret_cast<xsltTransformContextPtr
>(c);
218 xmlNodePtr instruction_node =
219 reinterpret_cast<xmlNodePtr
>(instruction_node_);
222 xslt_ctxt->_private);
225 key.first =
reinterpret_cast<const char *
>(instruction_node->name);
226 if (instruction_node->ns !=
NULL && instruction_node->ns->href !=
NULL)
228 reinterpret_cast<const char *
>(instruction_node->ns->href);
236 xmlNodePtr input_node =
237 reinterpret_cast<xmlNodePtr
>(input_node_);
253 found->second.first->pimpl_->xslt_ctxt = xslt_ctxt;
254 found->second.first->pimpl_->instruction_node = instruction_node;
258 found->second.first->process(inp_node, instr_node,
260 }
catch (
const std::exception & ex) {
264 found->second.first->report_error(
error.c_str());
267 "extension element '" +
269 found->second.first->report_error(
error.c_str());
273 found->second.first->pimpl_->xslt_ctxt =
NULL;
274 found->second.first->pimpl_->instruction_node =
NULL;
285 void make_vector_param(std::vector<const char*> &v,
290 xslt::stylesheet::param_type::const_iterator
i = p.begin(), end = p.end();
291 for (;
i != end; ++
i)
293 v.push_back(
i->first.c_str());
294 v.push_back(
i->second.c_str());
297 v.push_back(
static_cast<const char*
>(0));
304 static void error_cb(
void *c,
const char *message, ...)
306 xsltTransformContextPtr ctxt =
static_cast<xsltTransformContextPtr
>(c);
311 if ( ctxt->state == XSLT_STATE_OK )
312 ctxt->state = XSLT_STATE_STOPPED;
316 s_impl->
error_.append(
"\n");
322 va_start(ap, message);
326 s_impl->
error_.append(formatted);
334 xmlNodePtr node = ctxt->inst;
336 if ((node->type == XML_DOCUMENT_NODE) ||
337 (node->type == XML_HTML_DOCUMENT_NODE)) {
338 xmlDocPtr d = (xmlDocPtr) node;
340 filename =
reinterpret_cast<const char *
>(d->URL);
342 line = xmlGetLineNo(node);
343 if (node->doc !=
NULL)
344 if (node->doc->URL !=
NULL)
345 filename =
reinterpret_cast<const char*
>(node->doc->URL);
367 xsltStylesheetPtr style = s_impl->
ss_;
369 std::vector<const char*> v;
371 make_vector_param(v, *p);
373 xsltTransformContextPtr ctxt = xsltNewTransformContext(style, doc);
374 ctxt->_private = s_impl;
375 xsltSetTransformErrorFunc(ctxt, ctxt, error_cb);
378 for (ext_funcs_map_type::iterator k = s_impl->
ext_functions_.begin();
380 if (xsltRegisterExtFunction(
382 reinterpret_cast<const xmlChar*
>(k->first.first.c_str()),
383 reinterpret_cast<const xmlChar*
>(k->first.second.c_str()),
385 xsltFreeTransformContext(ctxt);
392 for (ext_elems_map_type::iterator k = s_impl->
ext_elements_.begin();
394 if (xsltRegisterExtElement(
396 reinterpret_cast<const xmlChar*
>(k->first.first.c_str()),
397 reinterpret_cast<const xmlChar*
>(k->first.second.c_str()),
398 reinterpret_cast<xsltTransformFunction
>
400 xsltFreeTransformContext(ctxt);
415 xsltApplyStylesheetUser(style, doc, p ? &v[0] : 0,
NULL,
NULL, ctxt);
427 xsltFreeTransformContext(ctxt);
440 if ( s_impl->
error_.empty() )
441 s_impl->
error_ =
"unknown XSLT transformation error";
457 xsltFreeStylesheet(pimpl_->ss_);
461 pimpl_->ss_->_private = refcount;
470 std::unique_ptr<impl::stylesheet_impl>
474 xmlDocPtr xmldoc =
static_cast<xmlDocPtr
>(doc.
get_doc_data());
476 if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
479 if (pimpl_->error_.empty())
480 pimpl_->error_ =
"unknown XSLT parser error";
501 xmlDocPtr xmldoc =
static_cast<xmlDocPtr
>(
503 std::unique_ptr<impl::stylesheet_impl>
506 if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
509 if (pimpl_->error_.empty())
510 pimpl_->error_ =
"unknown XSLT parser error";
531 std::unique_ptr<impl::stylesheet_impl>
536 xmlDocPtr xmldoc =
static_cast<xmlDocPtr
>(doc.
get_doc_data());
538 if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
541 if (pimpl_->error_.empty())
542 pimpl_->error_ =
"unknown XSLT parser error";
562 std::unique_ptr<impl::stylesheet_impl>
566 xmlDocPtr xmldoc =
static_cast<xmlDocPtr
>(doc.
get_doc_data());
568 if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
571 if (pimpl_->error_.empty())
572 pimpl_->error_ =
"unknown XSLT parser error";
610 ext_funcs_map_type::iterator found(pimpl_->ext_functions_.find(
key));
612 if (found != pimpl_->ext_functions_.end()) {
614 delete found->second.first;
643 ext_elems_map_type::iterator found(pimpl_->ext_elements_.find(
key));
645 if (found != pimpl_->ext_elements_.end()) {
647 delete found->second.first;
658 if (pimpl_ !=
NULL) {
660 for (ext_funcs_map_type::iterator k = pimpl_->ext_functions_.begin();
661 k != pimpl_->ext_functions_.end(); ++k) {
663 delete k->second.first;
667 for (ext_elems_map_type::iterator k = pimpl_->ext_elements_.begin();
668 k != pimpl_->ext_elements_.end(); ++k) {
670 delete k->second.first;
695 if (
this != &other) {
697 pimpl_ = other.pimpl_;
708 xmlDocPtr xmldoc = apply_stylesheet(pimpl_,
input,
NULL, messages_);
722 xmlDocPtr xmldoc = apply_stylesheet(pimpl_,
input, &with_params, messages_);
The xml::document_proxy class to be a relay between XSLT results and the document.
The xml::document class is used to hold the XML tree and various bits of information about it.
void set_doc_data(void *data)
void * release_doc_data(void)
void * get_doc_data(void)
void * get_doc_data_read_only(void) const
The xml::error_message class is used to store a single error message which may appear while parsing o...
The xml::error_messages class is used to store all the error message which are collected while parsin...
const error_messages_type & get_messages(void) const
Get the error messages.
const char * get(void) const
The xml::node class is used to hold information about one XML node.
void set_node_data(void *data)
The xml::parser_exception class is used to store parsing and validating exception information.
This exception class is thrown by xmlwrapp for all runtime XSLT-related errors.
The XSLT extension element object is used to be a base class for the user provided XSLT extension ele...
The XSLT extension function object is used to be a base class for the user provided XSLT functions.
A helper class to add a syntactic sugar when single quoted parameters need to added for xslt transfol...
The xslt::stylesheet class is used to hold information about an XSLT stylesheet.
stylesheet & operator=(stylesheet &&other)
Moving assignment.
void register_extension_element(extension_element *ee, const char *name, const char *uri, xml::ownership_type ownership=xml::type_not_own)
Register an XSLT extension element.
virtual ~stylesheet(void)
Clean up after an xslt::stylesheet.
stylesheet(const char *filename)
Create a new xslt::stylesheet object and load and parse the stylesheet in the given filename.
void attach_refcount(void)
void register_extension_function(extension_function *ef, const char *name, const char *uri, xml::ownership_type ownership=xml::type_not_own)
Register an XSLT extension function.
xml::document_proxy apply(const xml::document &doc, xml::error_messages *messages_=NULL)
Apply this stylesheet to the given XML document.
The xslt::xpath_object class is used to store extension function arguments and return values.
This file contains definition of the xslt::impl::extension_element_impl class.
This file contains definition of the xslt::impl::extension_function_impl class.
This file contains the definition of the xml::document class.
This file contains the definition of the xml::exception class.
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
int strcmp(const char *str1, const char *str2)
void clear_https_messages(void)
void printf2string(std::string &s, const char *message, va_list ap)
void collect_https_messages(xml::error_messages &append_to)
ownership_type
Used to specify if xmlwrapp should grab the ownership of various objects.
@ type_own
Grab the ownership, i.e.
@ type_warnings_not_errors
Do not treat warnings as errors.
bool is_xml_output_method(xsltStylesheetPtr ss)
void destroy_stylesheet(xsltStylesheetPtr ss)
bool save_to_file(xmlDocPtr doc, xsltStylesheetPtr ss, const char *filename, int)
void save_to_string(xmlDocPtr doc, xsltStylesheetPtr ss, std::string &s)
void set_ownership(bool owe)
ext_funcs_map_type ext_functions_
std::vector< xmlNodePtr > nodes_to_free_
xml::error_messages * messages_
ext_elems_map_type ext_elements_
void xslt_ext_func_cb(void *c, int arg_num)
void xslt_ext_element_cb(void *c, void *input_node_, void *instruction_node_, void *compiled_stylesheet_info)
This file contains the definition of the xslt::stylesheet class.
This file contains definition of the xslt::impl::stylesheet_impl class.
std::pair< std::string, std::string > ext_elem_key
std::pair< std::string, std::string > ext_func_key
This file contains the definition of the xslt::exception class.