NCBI C++ ToolKit
stylesheet.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
3  * All Rights Reserved
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name of the Author nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
23  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * $Id: stylesheet.cpp 99402 2023-03-22 18:09:14Z satskyse $
35  * NOTE: This file was modified from its original version 0.6.0
36  * to fit the NCBI C++ Toolkit build framework and
37  * API and functionality requirements.
38  */
39 
40 /** @file
41  * This file contains the implementation of the xslt::stylesheet class.
42 **/
43 
44 // xmlwrapp includes
49 
50 #include "utility.hpp"
51 #include "document_impl.hpp"
52 
53 // libxslt includes
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>
61 
62 // standard includes
63 #include <stdexcept>
64 #include <memory>
65 #include <string>
66 #include <vector>
67 #include <map>
68 #include <string.h>
69 
72 
73 #include "stylesheet_impl.hpp"
74 #include "https_input_impl.hpp"
75 
76 
77 namespace xslt {
78  namespace impl {
79  bool is_xml_output_method (xsltStylesheetPtr ss)
80  {
81  if (ss->method == NULL)
82  return true;
83  return strcmp(reinterpret_cast<const char *>(ss->method),
84  "xml") == 0;
85  }
86 
87  void destroy_stylesheet (xsltStylesheetPtr ss)
88  {
89  if (ss->_private == NULL)
90  xsltFreeStylesheet(ss);
91  else {
92  stylesheet_refcount * ss_rc =
93  static_cast<stylesheet_refcount *>(ss->_private);
94  if (ss_rc->dec_ref() == 0) {
95  delete ss_rc;
96  xsltFreeStylesheet(ss);
97  }
98  }
99  }
100 
101  void save_to_string(xmlDocPtr doc,
102  xsltStylesheetPtr ss,
103  std::string & s)
104  {
105  xmlChar * xml_string;
106  int xml_string_length;
107 
108  if (xsltSaveResultToString(&xml_string,
109  &xml_string_length, doc, ss) >= 0)
110  {
111  xml::impl::xmlchar_helper helper(xml_string);
112  if (xml_string_length)
113  s.assign(helper.get(), xml_string_length);
114  }
115  }
116 
117  bool
118  save_to_file(xmlDocPtr doc,
119  xsltStylesheetPtr ss,
120  const char * filename,
121  int /* compression_level */)
122  {
123  return xsltSaveResultToFilename(filename, doc, ss, 0) >= 0;
124  }
125  } // End of impl namespace
126 } // End of xslt namespace
127 
128 
130 {
131  for (std::vector<xmlNodePtr>::const_iterator k = nodes_to_free_.begin();
132  k != nodes_to_free_.end(); ++k)
133  xmlFreeNode(*k);
134  nodes_to_free_.clear();
135 }
136 
137 
138 extern "C" {
139 
140  // XSLT extension function callback
141  void xslt_ext_func_cb(void *c, int arg_num)
142  {
143  xmlXPathParserContext * ctxt =
144  reinterpret_cast<xmlXPathParserContext *>(c);
145  xsltTransformContextPtr xslt_ctxt =
146  xsltXPathGetTransformContext(ctxt);
147  xslt::impl::stylesheet_impl * s_impl =
148  reinterpret_cast<xslt::impl::stylesheet_impl *>(
149  xslt_ctxt->_private);
150  xmlNodePtr current_node = ctxt->context->node;
151  xmlDocPtr current_doc = ctxt->context->doc;
152 
153  // Search for a registered extension function
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);
159 
160  ext_funcs_map_type::iterator found = s_impl->ext_functions_.find(key);
161  if (found == s_impl->ext_functions_.end())
162  return; // No extension function were found
163 
164  // The corresponding extension function has been found.
165  // Prepare parameters and call it
166  std::vector<xslt::xpath_object> args;
167  xml::node node;
168  xml::document doc;
169 
170  // Prepare arguments for the extension function call. Arguments are
171  // coming in the reverse order.
172  args.reserve(arg_num);
173  for (int k = 0; k < arg_num; ++k) {
174  xmlXPathObjectPtr current_arg = valuePop(ctxt);
175 
176  args.insert(args.begin(),
177  xslt::xpath_object(reinterpret_cast<void*>(current_arg)));
178  args[0].set_from_xslt();
179  }
180 
181 
182  // Wrap libxml2 data with xmlwrapp and make sure that xmlwrapp does NOT
183  // have ownership on the node and the document.
184  node.set_node_data(current_node);
185  doc.set_doc_data(current_doc);
186  doc.pimpl_->set_ownership(false);
187 
188  // Set the context to make error reporting and setting retval
189  // working properly
190  found->second.first->pimpl_->xpath_parser_ctxt = ctxt;
191 
192  // Make a call
193  try {
194  found->second.first->execute(args, node, doc);
195  } catch (const std::exception & ex) {
196  std::string error("Exception in the user extension function '" +
197  key.first + "': " + std::string(ex.what()));
198  found->second.first->report_error(error.c_str());
199  } catch (...) {
200  std::string error("Unknown exception in the user "
201  "extension function '" + key.first + "'");
202  found->second.first->report_error(error.c_str());
203  }
204 
205  // Clear the context
206  found->second.first->pimpl_->xpath_parser_ctxt = NULL;
207 
208  return;
209  }
210 
211  // XSLT extension element callback
212  void xslt_ext_element_cb(void *c, void *input_node_,
213  void *instruction_node_,
214  void *compiled_stylesheet_info)
215  {
216  xsltTransformContextPtr xslt_ctxt =
217  reinterpret_cast<xsltTransformContextPtr>(c);
218  xmlNodePtr instruction_node =
219  reinterpret_cast<xmlNodePtr>(instruction_node_);
220  xslt::impl::stylesheet_impl * s_impl =
221  reinterpret_cast<xslt::impl::stylesheet_impl *>(
222  xslt_ctxt->_private);
223 
225  key.first = reinterpret_cast<const char *>(instruction_node->name);
226  if (instruction_node->ns != NULL && instruction_node->ns->href != NULL)
227  key.second =
228  reinterpret_cast<const char *>(instruction_node->ns->href);
229 
230  ext_elems_map_type::iterator found = s_impl->ext_elements_.find(key);
231  if (found == s_impl->ext_elements_.end())
232  return; // No extension element were found
233 
234  // The corresponding extension element has been found.
235  // Prepare the parameters.
236  xmlNodePtr input_node =
237  reinterpret_cast<xmlNodePtr>(input_node_);
238 
239  xml::node inp_node;
240  xml::node instr_node;
241  xml::node insert_node;
242  xml::document doc;
243 
244  // Wrap libxml2 data with xmlwrapp and make sure that xmlwrapp does NOT
245  // have ownership on the nodes and the document.
246  inp_node.set_node_data(input_node);
247  instr_node.set_node_data(instruction_node);
248  insert_node.set_node_data(xslt_ctxt->insert);
249  doc.set_doc_data(xslt_ctxt->xpathCtxt->doc);
250  doc.pimpl_->set_ownership(false);
251 
252  // Set the context to make error reporting working properly
253  found->second.first->pimpl_->xslt_ctxt = xslt_ctxt;
254  found->second.first->pimpl_->instruction_node = instruction_node;
255 
256  // Make a call
257  try {
258  found->second.first->process(inp_node, instr_node,
259  insert_node, doc);
260  } catch (const std::exception & ex) {
261  std::string error("Exception in the user extension element '" +
262  key.first + "': " +
263  std::string(ex.what()));
264  found->second.first->report_error(error.c_str());
265  } catch (...) {
266  std::string error("Unknown error in the user "
267  "extension element '" +
268  key.first + "'");
269  found->second.first->report_error(error.c_str());
270  }
271 
272  // Clear the context
273  found->second.first->pimpl_->xslt_ctxt = NULL;
274  found->second.first->pimpl_->instruction_node = NULL;
275 
276  return;
277  }
278 
279 } // extern "C"
280 
281 
282 namespace
283 {
284 
285 void make_vector_param(std::vector<const char*> &v,
287 {
288  v.reserve(p.size());
289 
290  xslt::stylesheet::param_type::const_iterator i = p.begin(), end = p.end();
291  for (; i != end; ++i)
292  {
293  v.push_back(i->first.c_str());
294  v.push_back(i->second.c_str());
295  }
296 
297  v.push_back(static_cast<const char*>(0));
298 }
299 
300 
301 extern "C"
302 {
303 
304 static void error_cb(void *c, const char *message, ...)
305 {
306  xsltTransformContextPtr ctxt = static_cast<xsltTransformContextPtr>(c);
308  static_cast<xslt::impl::stylesheet_impl*>(ctxt->_private);
309 
310  // tell the processor to stop when it gets a chance:
311  if ( ctxt->state == XSLT_STATE_OK )
312  ctxt->state = XSLT_STATE_STOPPED;
313 
314  // concatenate all error messages:
315  if ( s_impl->errors_occured_ )
316  s_impl->error_.append("\n");
317  s_impl->errors_occured_ = true;
318 
319  std::string formatted;
320 
321  va_list ap;
322  va_start(ap, message);
323  xml::impl::printf2string(formatted, message, ap);
324  va_end(ap);
325 
326  s_impl->error_.append(formatted);
327 
328  if (s_impl->messages_ != NULL) {
329  // Need to insert the error information into the user provided container
330  long line = 0;
331  std::string filename;
332 
333  // Supposedly the current served node
334  xmlNodePtr node = ctxt->inst;
335  if (node != NULL) {
336  if ((node->type == XML_DOCUMENT_NODE) ||
337  (node->type == XML_HTML_DOCUMENT_NODE)) {
338  xmlDocPtr d = (xmlDocPtr) node;
339  if (d->URL != NULL)
340  filename = reinterpret_cast<const char *>(d->URL);
341  } else {
342  line = xmlGetLineNo(node);
343  if (node->doc != NULL)
344  if (node->doc->URL != NULL)
345  filename = reinterpret_cast<const char*>(node->doc->URL);
346  }
347  }
348 
349  s_impl->messages_->get_messages().push_back(
351  formatted,
353  line, filename));
354  }
355 }
356 
357 } // extern "C"
358 
359 
360 
361 xmlDocPtr apply_stylesheet(xslt::impl::stylesheet_impl *s_impl,
362  xmlDocPtr doc,
364  xml::error_messages * messages_ = NULL
365  )
366 {
367  xsltStylesheetPtr style = s_impl->ss_;
368 
369  std::vector<const char*> v;
370  if (p)
371  make_vector_param(v, *p);
372 
373  xsltTransformContextPtr ctxt = xsltNewTransformContext(style, doc);
374  ctxt->_private = s_impl;
375  xsltSetTransformErrorFunc(ctxt, ctxt, error_cb);
376 
377  // Register extension functions
378  for (ext_funcs_map_type::iterator k = s_impl->ext_functions_.begin();
379  k != s_impl->ext_functions_.end(); ++k) {
380  if (xsltRegisterExtFunction(
381  ctxt,
382  reinterpret_cast<const xmlChar*>(k->first.first.c_str()),
383  reinterpret_cast<const xmlChar*>(k->first.second.c_str()),
384  reinterpret_cast<xmlXPathFunction>(xslt_ext_func_cb)) != 0) {
385  xsltFreeTransformContext(ctxt);
386  throw xslt::exception("Error registering extension function " +
387  k->first.first);
388  }
389  }
390 
391  // Register extension elements
392  for (ext_elems_map_type::iterator k = s_impl->ext_elements_.begin();
393  k != s_impl->ext_elements_.end(); ++k) {
394  if (xsltRegisterExtElement(
395  ctxt,
396  reinterpret_cast<const xmlChar*>(k->first.first.c_str()),
397  reinterpret_cast<const xmlChar*>(k->first.second.c_str()),
398  reinterpret_cast<xsltTransformFunction>
399  (xslt_ext_element_cb)) != 0) {
400  xsltFreeTransformContext(ctxt);
401  throw xslt::exception("Error registering extension element " +
402  k->first.first);
403  }
404  }
405 
406  // clear the error flag before applying the stylesheet
407  s_impl->errors_occured_ = false;
408  s_impl->messages_ = messages_;
409 
410  // Wierd way to collect https warnings: via tls in the custom IO handler
411  // See https_input_impl.*
412  if (s_impl->messages_)
414  xmlDocPtr result =
415  xsltApplyStylesheetUser(style, doc, p ? &v[0] : 0, NULL, NULL, ctxt);
416  if (s_impl->messages_)
418 
419  // This is a part of a hack of leak-less handling nodeset return values
420  // from XSLT extension functions. XSLT frees nodes in a nodeset too early
421  // so the boolval is not set to 1 to free them automatically. Instead the
422  // nodes are memorized in a vector. These nodes are freed here, i.e. when
423  // the transformation is completed.
424  // See extension_function.cpp and xpath_object.cpp as well.
425  s_impl->clear_nodes();
426 
427  xsltFreeTransformContext(ctxt);
428 
429  // it's possible there was an error that didn't prevent creation of some
430  // (incorrect) document
431  if ( result && s_impl->errors_occured_ )
432  {
433  xmlFreeDoc(result);
434  return NULL;
435  }
436 
437  if ( !result )
438  {
439  // set generic error message if nothing more specific is known
440  if ( s_impl->error_.empty() )
441  s_impl->error_ = "unknown XSLT transformation error";
442  return NULL;
443  }
444 
445  return result;
446 }
447 
448 } // end of anonymous namespace
449 
450 
452 {
453  impl::stylesheet_refcount * refcount;
454  try {
455  refcount = new impl::stylesheet_refcount;
456  } catch (...) {
457  xsltFreeStylesheet(pimpl_->ss_);
458  throw;
459  }
460  refcount->inc_ref();
461  pimpl_->ss_->_private = refcount;
462 }
463 
464 
465 xslt::stylesheet::stylesheet(const char *filename)
466 {
467  if (!filename)
468  throw xslt::exception("invalid file name");
469 
470  std::unique_ptr<impl::stylesheet_impl>
471  ap(pimpl_ = new impl::stylesheet_impl);
472  xml::error_messages msgs;
473  xml::document doc(filename, &msgs, xml::type_warnings_not_errors);
474  xmlDocPtr xmldoc = static_cast<xmlDocPtr>(doc.get_doc_data());
475 
476  if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
477  {
478  // TODO error_ can't get set yet. Need changes from libxslt first
479  if (pimpl_->error_.empty())
480  pimpl_->error_ = "unknown XSLT parser error";
481 
482  msgs.get_messages().push_back(xml::error_message(
483  pimpl_->error_,
485  0, filename));
486  throw xml::parser_exception(msgs);
487  }
488 
489  attach_refcount();
490 
491  // if we got this far, the xmldoc we gave to xsltParseStylesheetDoc is
492  // now owned by the stylesheet and will be cleaned up in our destructor.
493  doc.release_doc_data();
494  ap.release();
495 }
496 
497 
499 {
500  xml::document doc_copy(doc); /* NCBI_FAKE_WARNING */
501  xmlDocPtr xmldoc = static_cast<xmlDocPtr>(
502  doc_copy.get_doc_data());
503  std::unique_ptr<impl::stylesheet_impl>
504  ap(pimpl_ = new impl::stylesheet_impl);
505 
506  if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
507  {
508  // TODO error_ can't get set yet. Need changes from libxslt first
509  if (pimpl_->error_.empty())
510  pimpl_->error_ = "unknown XSLT parser error";
511 
512  xml::error_messages messages;
513  messages.get_messages().push_back(xml::error_message(
514  pimpl_->error_,
516  0, ""));
517  throw xml::parser_exception(messages);
518  }
519 
520  attach_refcount();
521 
522  // if we got this far, the xmldoc we gave to xsltParseStylesheetDoc is
523  // now owned by the stylesheet and will be cleaned up in our destructor.
524  doc_copy.release_doc_data();
525  ap.release();
526 }
527 
528 
530 {
531  std::unique_ptr<impl::stylesheet_impl>
532  ap(pimpl_ = new impl::stylesheet_impl);
533  xml::error_messages msgs;
534  xml::document doc(data, size, &msgs,
536  xmlDocPtr xmldoc = static_cast<xmlDocPtr>(doc.get_doc_data());
537 
538  if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
539  {
540  // TODO error_ can't get set yet. Need changes from libxslt first
541  if (pimpl_->error_.empty())
542  pimpl_->error_ = "unknown XSLT parser error";
543 
544  msgs.get_messages().push_back(xml::error_message(
545  pimpl_->error_,
547  0, ""));
548  throw xml::parser_exception(msgs);
549  }
550 
551  attach_refcount();
552 
553  // if we got this far, the xmldoc we gave to xsltParseStylesheetDoc is
554  // now owned by the stylesheet and will be cleaned up in our destructor.
555  doc.release_doc_data();
556  ap.release();
557 }
558 
559 
560 xslt::stylesheet::stylesheet (std::istream & stream)
561 {
562  std::unique_ptr<impl::stylesheet_impl>
563  ap(pimpl_ = new impl::stylesheet_impl);
564  xml::error_messages msgs;
565  xml::document doc(stream, &msgs, xml::type_warnings_not_errors);
566  xmlDocPtr xmldoc = static_cast<xmlDocPtr>(doc.get_doc_data());
567 
568  if ( (pimpl_->ss_ = xsltParseStylesheetDoc(xmldoc)) == 0)
569  {
570  // TODO error_ can't get set yet. Need changes from libxslt first
571  if (pimpl_->error_.empty())
572  pimpl_->error_ = "unknown XSLT parser error";
573 
574  msgs.get_messages().push_back(xml::error_message(
575  pimpl_->error_,
577  0, ""));
578  throw xml::parser_exception(msgs);
579  }
580 
581  attach_refcount();
582 
583  // if we got this far, the xmldoc we gave to xsltParseStylesheetDoc is
584  // now owned by the stylesheet and will be cleaned up in our destructor.
585  doc.release_doc_data();
586  ap.release();
587 }
588 
589 
590 void
592  const char * name,
593  const char * uri,
594  xml::ownership_type ownership)
595 {
596  if (name == NULL) {
597  if (ownership == xml::type_own)
598  delete ef;
599  throw xslt::exception("Extension function name is uninitialised");
600  }
601 
602  if (uri == NULL) {
603  if (ownership == xml::type_own)
604  delete ef;
605  throw xslt::exception("Extension function URI is uninitialised");
606  }
607 
608  ext_func_key key = std::pair<std::string,
609  std::string>(name, uri);
610  ext_funcs_map_type::iterator found(pimpl_->ext_functions_.find(key));
611 
612  if (found != pimpl_->ext_functions_.end()) {
613  if (found->second.second == xml::type_own)
614  delete found->second.first;
615  }
616 
617  pimpl_->ext_functions_[ key ] = std::pair<extension_function *,
618  xml::ownership_type>(ef, ownership);
619  return;
620 }
621 
622 
623 void
625  const char * name,
626  const char * uri,
627  xml::ownership_type ownership)
628 {
629  if (name == NULL) {
630  if (ownership == xml::type_own)
631  delete ee;
632  throw xslt::exception("Extension element name is uninitialised");
633  }
634 
635  if (uri == NULL) {
636  if (ownership == xml::type_own)
637  delete ee;
638  throw xslt::exception("Extension element URI is uninitialised");
639  }
640 
641  ext_elem_key key = std::pair<std::string,
642  std::string>(name, uri);
643  ext_elems_map_type::iterator found(pimpl_->ext_elements_.find(key));
644 
645  if (found != pimpl_->ext_elements_.end()) {
646  if (found->second.second == xml::type_own)
647  delete found->second.first;
648  }
649 
650  pimpl_->ext_elements_[ key ] = std::pair<extension_element *,
651  xml::ownership_type>(ee, ownership);
652  return;
653 }
654 
655 
657 {
658  if (pimpl_ != NULL) {
659  // Delete extension functions we owe
660  for (ext_funcs_map_type::iterator k = pimpl_->ext_functions_.begin();
661  k != pimpl_->ext_functions_.end(); ++k) {
662  if (k->second.second == xml::type_own)
663  delete k->second.first;
664  }
665 
666  // Delete extension elements we owe
667  for (ext_elems_map_type::iterator k = pimpl_->ext_elements_.begin();
668  k != pimpl_->ext_elements_.end(); ++k) {
669  if (k->second.second == xml::type_own)
670  delete k->second.first;
671  }
672 
673  if (pimpl_->ss_)
674  xslt::impl::destroy_stylesheet(pimpl_->ss_);
675  delete pimpl_;
676  }
677 }
678 
679 
681 {
682  destroy();
683 }
684 
685 
687  pimpl_(other.pimpl_)
688 {
689  other.pimpl_ = NULL;
690 }
691 
692 
694 {
695  if (this != &other) {
696  destroy();
697  pimpl_ = other.pimpl_;
698  other.pimpl_ = NULL;
699  }
700  return *this;
701 }
702 
703 
705  xml::error_messages * messages_)
706 {
707  xmlDocPtr input = static_cast<xmlDocPtr>(doc.get_doc_data_read_only());
708  xmlDocPtr xmldoc = apply_stylesheet(pimpl_, input, NULL, messages_);
709 
710  if ( !xmldoc )
711  throw xslt::exception(pimpl_->error_);
712 
713  return xml::document_proxy(xmldoc, pimpl_->ss_);
714 }
715 
716 
718  const param_type &with_params,
719  xml::error_messages * messages_ )
720 {
721  xmlDocPtr input = static_cast<xmlDocPtr>(doc.get_doc_data_read_only());
722  xmlDocPtr xmldoc = apply_stylesheet(pimpl_, input, &with_params, messages_);
723 
724  if ( !xmldoc )
725  throw xslt::exception(pimpl_->error_);
726 
727  return xml::document_proxy(xmldoc, pimpl_->ss_);
728 }
729 
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.
Definition: document.hpp:80
impl::doc_impl * pimpl_
Definition: document.hpp:770
void set_doc_data(void *data)
Definition: document.cpp:998
void * release_doc_data(void)
Definition: document.cpp:1028
void * get_doc_data(void)
Definition: document.cpp:1020
void * get_doc_data_read_only(void) const
Definition: document.cpp:1024
The xml::error_message class is used to store a single error message which may appear while parsing o...
Definition: errors.hpp:50
@ type_error
error
Definition: errors.hpp:55
The xml::error_messages class is used to store all the error message which are collected while parsin...
Definition: errors.hpp:137
const error_messages_type & get_messages(void) const
Get the error messages.
Definition: errors.cpp:98
const char * get(void) const
Definition: utility.hpp:81
The xml::node class is used to hold information about one XML node.
Definition: node.hpp:106
void set_node_data(void *data)
Definition: node.cpp:746
The xml::parser_exception class is used to store parsing and validating exception information.
Definition: errors.hpp:214
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...
Definition: stylesheet.hpp:70
The xslt::stylesheet class is used to hold information about an XSLT stylesheet.
Definition: stylesheet.hpp:130
stylesheet & operator=(stylesheet &&other)
Moving assignment.
Definition: stylesheet.cpp:693
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.
Definition: stylesheet.cpp:624
virtual ~stylesheet(void)
Clean up after an xslt::stylesheet.
Definition: stylesheet.cpp:680
stylesheet(const char *filename)
Create a new xslt::stylesheet object and load and parse the stylesheet in the given filename.
Definition: stylesheet.cpp:465
void attach_refcount(void)
Definition: stylesheet.cpp:451
void destroy(void)
Definition: stylesheet.cpp:656
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.
Definition: stylesheet.cpp:591
xml::document_proxy apply(const xml::document &doc, xml::error_messages *messages_=NULL)
Apply this stylesheet to the given XML document.
Definition: stylesheet.cpp:704
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.
char data[12]
Definition: iconv.c:80
string
Definition: cgiapp.hpp:690
#define NULL
Definition: ncbistd.hpp:225
void destroy(P pT)
static int input()
int i
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)
Definition: odbc_utils.hpp:160
void clear_https_messages(void)
void printf2string(std::string &s, const char *message, va_list ap)
Definition: utility.cpp:79
void collect_https_messages(xml::error_messages &append_to)
ownership_type
Used to specify if xmlwrapp should grab the ownership of various objects.
Definition: ownership.hpp:43
@ type_own
Grab the ownership, i.e.
Definition: ownership.hpp:44
@ type_warnings_not_errors
Do not treat warnings as errors.
Definition: errors.hpp:261
bool is_xml_output_method(xsltStylesheetPtr ss)
Definition: stylesheet.cpp:79
void destroy_stylesheet(xsltStylesheetPtr ss)
Definition: stylesheet.cpp:87
bool save_to_file(xmlDocPtr doc, xsltStylesheetPtr ss, const char *filename, int)
Definition: stylesheet.cpp:118
void save_to_string(xmlDocPtr doc, xsltStylesheetPtr ss, std::string &s)
Definition: stylesheet.cpp:101
XML library namespace.
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)
Definition: stylesheet.cpp:141
void xslt_ext_element_cb(void *c, void *input_node_, void *instruction_node_, void *compiled_stylesheet_info)
Definition: stylesheet.cpp:212
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
else result
Definition: token2.c:20
This file contains the definition of the xslt::exception class.
Modified on Fri Sep 20 14:58:24 2024 by modify_doxy.py rev. 669887