71 #include <libxml/tree.h>
72 #include <libxml/parser.h>
73 #include <libxml/xpath.h>
74 #include <libxml/xpathInternals.h>
75 #include <libxml/xmlsave.h>
116 return cb_(l_node, r_node);
127 node2doc (xmlNodePtr xmlnode) : xmlnode_(xmlnode), prev_(0), next_(0) {
128 xmldoc_ = xmlNewDoc(0);
129 if (!xmldoc_)
throw std::bad_alloc();
131 xmldoc_->children = xmlnode_;
132 xmldoc_->last = xmlnode_;
139 xmldoc_->children = 0;
148 xmlDocPtr get_doc (
void)
160 compare_attr (
const char *attr_name) : name_(attr_name) { }
162 bool operator() (xmlNodePtr lhs, xmlNodePtr rhs) {
163 xmlAttrPtr attr_l, attr_r;
177 xmlChar *value_l, *value_r;
179 if (dtd_l) value_l =
const_cast<xmlChar*
>
180 (dtd_l->def_prop_->defaultValue);
181 else value_l = xmlNodeListGetString(lhs->doc, attr_l->children, 1);
183 if (dtd_r) value_r =
const_cast<xmlChar*
>
184 (dtd_r->def_prop_->defaultValue);
185 else value_r = xmlNodeListGetString(rhs->doc, attr_r->children, 1);
187 int rc = xmlStrcmp(value_l, value_r);
189 if (!dtd_l) xmlFree(value_l);
190 if (!dtd_r) xmlFree(value_r);
202 insert_node (xmlNodePtr parent) : parent_(parent) { }
203 void operator() (xmlNodePtr child) { xmlAddChild(parent_, child); }
209 xmlNodePtr find_element(
const char *name,
210 xmlNodePtr
first,
const ns *nspace) {
212 if (
first->type == XML_ELEMENT_NODE &&
213 xmlStrcmp(
first->name,
214 reinterpret_cast<const xmlChar*
>(name)) == 0) {
226 xmlNodePtr find_element(xmlNodePtr
first) {
228 if (
first->type == XML_ELEMENT_NODE)
return first;
238 void set_new_doc(xmlNodePtr
node, xmlDocPtr old_doc,
245 if (
node->doc == old_doc)
248 xmlNsPtr def =
node->nsDef;
250 if (def->context == old_doc)
251 def->context = new_doc;
255 xmlAttrPtr attr =
node->properties;
257 if (attr->doc == old_doc)
259 if (attr->children && attr->children->doc == old_doc)
260 attr->children->doc = new_doc;
266 set_new_doc(
node, old_doc, new_doc,
true);
273 void get_used_out_namespaces(xmlNodePtr
node,
274 std::vector<xmlNsPtr> & definitions,
275 std::vector<xmlNsPtr> & namespaces) {
279 xmlNsPtr def =
node->nsDef;
286 if (std::find(namespaces.begin(), namespaces.end(),
287 node->ns) == namespaces.end())
288 if (std::find(definitions.begin(), definitions.end(),
289 node->ns) == definitions.end())
290 namespaces.push_back(
node->ns);
292 xmlAttrPtr attr =
node->properties;
294 if (attr->ns !=
NULL)
295 if (std::find(namespaces.begin(), namespaces.end(),
296 attr->ns) == namespaces.end())
297 if (std::find(definitions.begin(), definitions.end(),
298 attr->ns) == definitions.end())
305 get_used_out_namespaces(
node, definitions, namespaces);
311 std::vector<xmlNsPtr> get_upper_namespaces(xmlNodePtr
node) {
312 std::vector<xmlNsPtr> namespaces;
318 xmlNsPtr def =
node->nsDef;
328 void update_ns_pointers(xmlNodePtr
node,
329 xmlNsPtr old_ns, xmlNsPtr new_ns) {
333 if (
node->ns == old_ns)
336 xmlAttrPtr attr =
node->properties;
338 if (attr->ns == old_ns)
345 update_ns_pointers(
node, old_ns, new_ns);
350 bool in_doc_dict(xmlDocPtr doc,
const xmlChar * s) {
353 if (doc->dict ==
NULL)
357 return xmlDictOwns(doc->dict, s) == 1;
360 void unlink_doc_dict(xmlDocPtr doc, xmlNodePtr
node) {
363 if (doc->dict ==
NULL)
368 if (in_doc_dict(doc,
node->name))
370 if (in_doc_dict(doc,
node->content))
371 node->content = xmlStrdup(
node->content);
373 xmlAttrPtr attr =
node->properties;
375 if (in_doc_dict(doc, attr->name))
376 attr->name = xmlStrdup(attr->name);
381 if (in_doc_dict(doc, attr->children->content))
382 attr->children->content = xmlStrdup(
383 attr->children->content);
389 unlink_doc_dict(doc,
node);
405 reinterpret_cast<const xmlChar*
>(
"blank"));
408 throw std::bad_alloc();
416 pimpl_->
xmlnode_ = xmlNewNode(0,
reinterpret_cast<const xmlChar*
>(name));
419 throw std::bad_alloc();
427 pimpl_->
xmlnode_ = xmlNewNode(0,
reinterpret_cast<const xmlChar*
>(name));
430 throw std::bad_alloc();
433 xmlNodePtr content_node = xmlNewText(
434 reinterpret_cast<const xmlChar*
>(content));
437 throw std::bad_alloc();
441 xmlFreeNode(content_node);
443 throw std::bad_alloc();
452 xmlNewCDataBlock(0,
reinterpret_cast<const xmlChar*
>(cdata_info.
t),
453 static_cast<int>(std::strlen(
454 cdata_info.
t)))) == 0) {
456 throw std::bad_alloc();
465 xmlNewComment(
reinterpret_cast<const xmlChar*
>(
466 comment_info.
t))) == 0) {
468 throw std::bad_alloc();
477 xmlNewPI(
reinterpret_cast<const xmlChar*
>(pi_info.
n),
478 reinterpret_cast<const xmlChar*
>(pi_info.
c))) == 0) {
480 throw std::bad_alloc();
489 xmlNewText(
reinterpret_cast<const xmlChar*
>(text_info.
t))) == 0) {
491 throw std::bad_alloc();
502 throw std::bad_alloc();
508 node tmp_node(other);
515 node tmp_node(other);
526 catch (std::exception & ex) {
541 if (
this != &other) {
559 xmlNodePtr parent = pimpl_->xmlnode_->parent;
563 "a node that it contains");
564 parent = parent->parent;
568 if (parent == pimpl_->xmlnode_)
570 "a node that it contains");
571 parent = parent->parent;
579 std::vector<xmlNsPtr> self_ns_definitions;
580 std::vector<xmlNsPtr> other_ns_definitions;
581 std::vector<xmlNsPtr> self_used_out_namespaces;
582 std::vector<xmlNsPtr> other_used_out_namespaces;
583 get_used_out_namespaces(pimpl_->xmlnode_, self_ns_definitions,
584 self_used_out_namespaces);
585 get_used_out_namespaces(other.
pimpl_->
xmlnode_, other_ns_definitions,
586 other_used_out_namespaces);
590 std::vector<xmlNsPtr>::iterator current = self_used_out_namespaces.begin();
591 std::vector<xmlNsPtr> other_definitions = get_upper_namespaces(
593 while (current != self_used_out_namespaces.end()) {
595 std::vector<xmlNsPtr>::iterator found = std::find(
596 other_used_out_namespaces.begin(),
597 other_used_out_namespaces.end(),
599 if (found != other_used_out_namespaces.end()) {
600 current = self_used_out_namespaces.erase(current);
601 other_used_out_namespaces.erase(found);
605 bool removed =
false;
606 for (std::vector<xmlNsPtr>::const_iterator
607 k = other_definitions.begin();
608 k != other_definitions.end(); ++k) {
609 if ((*current)->href == (*k)->href &&
610 (*current)->prefix == (*k)->prefix) {
611 current = self_used_out_namespaces.erase(current);
621 current = other_used_out_namespaces.begin();
622 std::vector<xmlNsPtr> self_definitions = get_upper_namespaces(
624 while (current != other_used_out_namespaces.end()) {
626 bool removed =
false;
627 for (std::vector<xmlNsPtr>::const_iterator
628 k = self_definitions.begin();
629 k != self_definitions.end(); ++k) {
630 if ((*current)->href == (*k)->href &&
631 (*current)->prefix == (*k)->prefix) {
632 current = other_used_out_namespaces.erase(current);
644 for (std::vector<xmlNsPtr>::const_iterator
645 k = self_used_out_namespaces.begin();
646 k != self_used_out_namespaces.end(); ++k) {
648 xml::ns new_ns = add_namespace_def((
const char *)((*k)->href),
649 (
const char *)((*k)->prefix));
650 if ((*k)->prefix !=
NULL) {
654 update_ns_pointers(pimpl_->xmlnode_, *k,
655 xmlSearchNs(
NULL, pimpl_->xmlnode_,
660 for (std::vector<xmlNsPtr>::const_iterator
661 k = other_used_out_namespaces.begin();
662 k != other_used_out_namespaces.end(); ++k) {
665 (
const char *)((*k)->prefix));
666 if ((*k)->prefix !=
NULL) {
677 xmlDocPtr self_doc = pimpl_->xmlnode_->doc;
680 if (self_doc != other_doc) {
681 set_new_doc(pimpl_->xmlnode_, self_doc, other_doc,
false);
685 if (self_doc != other_doc) {
695 unlink_doc_dict(self_doc, pimpl_->xmlnode_);
702 if (pimpl_->xmlnode_->_private !=
nullptr
704 if (pimpl_->xmlnode_->_private ==
nullptr) {
718 for (
auto child = pimpl_->xmlnode_->children; child !=
nullptr;
719 child = child->next) {
720 child->parent = pimpl_->xmlnode_;
722 for (
auto child = other.
pimpl_->
xmlnode_->children; child !=
nullptr;
723 child = child->next) {
748 pimpl_->xmlnode_ =
static_cast<xmlNodePtr
>(
data);
749 pimpl_->owner_ =
false;
754 return pimpl_->xmlnode_;
759 pimpl_->owner_ =
false;
760 return pimpl_->xmlnode_;
765 xmlNodeSetName(pimpl_->xmlnode_,
reinterpret_cast<const xmlChar*
>(name));
770 return reinterpret_cast<const char*
>(pimpl_->xmlnode_->name);
775 if (pimpl_->xmlnode_->type == XML_ELEMENT_NODE && content !=
NULL) {
776 xmlChar * encoded_content =
777 xmlEncodeSpecialChars(
778 pimpl_->xmlnode_->doc,
779 reinterpret_cast<const xmlChar*
>(content));
780 if (encoded_content ==
NULL)
781 throw std::bad_alloc();
782 xmlNodeSetContent(pimpl_->xmlnode_, encoded_content);
783 xmlFree(encoded_content);
786 xmlNodeSetContent(pimpl_->xmlnode_,
787 reinterpret_cast<const xmlChar*
>(content));
792 xmlNodeSetContent(pimpl_->xmlnode_,
793 reinterpret_cast<const xmlChar*
>(raw_content));
799 if (!content.
get())
return 0;
801 pimpl_->tmp_string = content.
get();
802 return pimpl_->tmp_string.c_str();
807 switch (pimpl_->xmlnode_->type) {
808 case XML_ELEMENT_NODE:
return type_element;
809 case XML_TEXT_NODE:
return type_text;
810 case XML_CDATA_SECTION_NODE:
return type_cdata;
811 case XML_ENTITY_REF_NODE:
return type_entity_ref;
812 case XML_ENTITY_NODE:
return type_entity;
813 case XML_PI_NODE:
return type_pi;
814 case XML_COMMENT_NODE:
return type_comment;
815 case XML_DOCUMENT_NODE:
return type_document;
816 case XML_DOCUMENT_TYPE_NODE:
return type_document_type;
817 case XML_DOCUMENT_FRAG_NODE:
return type_document_frag;
818 case XML_NOTATION_NODE:
return type_notation;
819 case XML_DTD_NODE:
return type_dtd;
820 case XML_ELEMENT_DECL:
return type_dtd_element;
821 case XML_ATTRIBUTE_DECL:
return type_dtd_attribute;
822 case XML_ENTITY_DECL:
return type_dtd_entity;
823 case XML_NAMESPACE_DECL:
return type_dtd_namespace;
824 case XML_XINCLUDE_START:
return type_xinclude;
825 case XML_XINCLUDE_END:
return type_xinclude;
826 default:
return type_element;
832 if (pimpl_->xmlnode_->type != XML_ELEMENT_NODE) {
833 throw xml::exception(
"get_attributes called on non-element node");
836 pimpl_->attrs_.set_data(pimpl_->xmlnode_);
837 return pimpl_->attrs_;
842 if (pimpl_->xmlnode_->type != XML_ELEMENT_NODE) {
843 throw xml::exception(
"get_attributes called on non-element node");
846 pimpl_->attrs_.set_data(pimpl_->xmlnode_);
847 return pimpl_->attrs_;
853 return get_attributes().find(name, nspace);
859 return get_attributes().find(name, nspace);
865 return pimpl_->xmlnode_->
ns
866 ?
xml::ns(
reinterpret_cast<const char*
>(pimpl_->xmlnode_->ns->prefix),
867 reinterpret_cast<const char*
>(pimpl_->xmlnode_->ns->href))
871 return xml::ns(pimpl_->xmlnode_->ns);
877 return get_namespace_definitions(pimpl_->xmlnode_,
type);
885 if (!
reinterpret_cast<xmlNodePtr
>(nd)->nsDef) {
886 return namespace_definitions;
888 for (xmlNs *
ns(
reinterpret_cast<xmlNodePtr
>(nd)->nsDef);
891 namespace_definitions.push_back(
892 xml::ns(
reinterpret_cast<const char*
>(
ns->prefix),
893 reinterpret_cast<const char*
>(
ns->href)));
896 namespace_definitions.push_back(
xml::ns(
ns));
899 return namespace_definitions;
904 if (prefix && prefix[0] ==
'\0') prefix =
NULL;
905 xmlNs * definition(xmlSearchNs(
NULL,
907 reinterpret_cast<const xmlChar*
>(prefix)));
910 pimpl_->xmlnode_->ns = definition;
919 return xml::ns(pimpl_->xmlnode_->ns);
922 pimpl_->xmlnode_->ns =
reinterpret_cast<xmlNs*
>(name_space.
unsafe_ns_);
926 if (prefix[0] ==
'\0') prefix =
NULL;
928 xmlNs * definition(xmlSearchNs(
929 NULL, pimpl_->xmlnode_,
930 reinterpret_cast<const xmlChar*
>(prefix)));
935 reinterpret_cast<const xmlChar*
>(name_space.
get_uri())))
937 "differs to the given");
938 pimpl_->xmlnode_->ns = definition;
940 return xml::ns(pimpl_->xmlnode_->ns);
949 "to namespace definitions");
950 if (!pimpl_->xmlnode_->nsDef)
951 return add_namespace_def(name_space.
get_uri(),
955 const char * patternPrefix(name_space.
get_prefix());
956 if (patternPrefix[0] ==
'\0') patternPrefix =
NULL;
958 xmlNs * current(pimpl_->xmlnode_->nsDef);
960 if (current->prefix ==
NULL) {
962 if (patternPrefix ==
NULL)
963 return add_matched_namespace_def(current, name_space.
get_uri(),
968 if (xmlStrEqual(
reinterpret_cast<const xmlChar*
>(patternPrefix),
970 return add_matched_namespace_def(current, name_space.
get_uri(),
973 current = current->next;
984 xml::ns_list_type::const_iterator
first(name_spaces.begin()),
985 last(name_spaces.end());
991 if (prefix && prefix[0] ==
'\0') prefix =
NULL;
992 if (uri && uri[0] ==
'\0') uri =
NULL;
993 xmlNs * newNs(xmlNewNs(pimpl_->xmlnode_,
994 reinterpret_cast<const xmlChar*
>(uri),
995 reinterpret_cast<const xmlChar*
>(prefix)));
997 throw std::bad_alloc();
1003 if (!pimpl_->xmlnode_->ns || !pimpl_->xmlnode_->ns->prefix)
1004 pimpl_->xmlnode_->ns = newNs;
1015 if (
type == type_throw_if_exists)
1017 if (
reinterpret_cast<xmlNs*
>(libxml2RawNamespace)->href !=
NULL )
1018 xmlFree((
char*)(
reinterpret_cast<xmlNs*
>(libxml2RawNamespace)->href));
1019 reinterpret_cast<xmlNs*
>(libxml2RawNamespace)->href =
1020 xmlStrdup(
reinterpret_cast<const xmlChar*
>(uri));
1021 return xml::ns(libxml2RawNamespace);
1027 if (prefix && prefix[0] ==
'\0') prefix =
NULL;
1028 xmlNs * found(xmlSearchNs(
NULL, pimpl_->xmlnode_,
1029 reinterpret_cast<const xmlChar*
>(prefix)));
1032 if (found)
return xml::ns(
reinterpret_cast<const char*
>(found->prefix),
1033 reinterpret_cast<const char*
>(found->href));
1043 if (prefix && prefix[0] ==
'\0')
1051 if (how == type_ns_def_erase_if_not_used) {
1053 if (
is_ns_used(pimpl_->xmlnode_, definition))
1072 replace_ns(pimpl_->xmlnode_, definition, default_namespace);
1078 if (!pimpl_->xmlnode_->ns)
return;
1079 if (!pimpl_->xmlnode_->ns->prefix)
return;
1080 pimpl_->xmlnode_->ns = xmlSearchNs(
NULL, pimpl_->xmlnode_,
NULL);
1085 std::deque<xml::ns_list_type> definitions_stack;
1086 definitions_stack.push_front(
1088 return erase_duplicate_ns_defs(pimpl_->xmlnode_, definitions_stack);
1093 std::deque<ns_list_type>& defs) {
1094 xmlNodePtr current =
reinterpret_cast<xmlNodePtr
>(nd)->children;
1096 erase_duplicate_ns_defs_single_node(current, defs);
1097 defs.push_front(get_namespace_definitions(current,
1099 erase_duplicate_ns_defs(current, defs);
1101 current = current->next;
1109 std::deque<ns_list_type>& defs) {
1110 xmlNsPtr
ns(
reinterpret_cast<xmlNodePtr
>(nd)->nsDef);
1112 xmlNsPtr replacement(
1113 reinterpret_cast<xmlNsPtr
>(
1114 find_replacement_ns_def(defs,
ns)));
1116 replace_ns(
reinterpret_cast<xmlNodePtr
>(nd),
ns, replacement);
1130 xmlNsPtr nspace(
reinterpret_cast<xmlNsPtr
>(
ns));
1131 for (std::deque<ns_list_type>::const_iterator k(defs.begin());
1132 k != defs.end(); ++k) {
1133 for (ns_list_type::const_iterator j(k->begin()); j != k->end(); ++j) {
1136 reinterpret_cast<xmlNsPtr
>(j->unsafe_ns_)->prefix) == 0) {
1139 reinterpret_cast<xmlNsPtr
>
1140 (j->unsafe_ns_)->href) == 0) {
1141 return j->unsafe_ns_;
1152 return erase_unused_ns_defs(pimpl_->xmlnode_);
1158 xmlNsPtr
ns(
reinterpret_cast<xmlNodePtr
>(nd)->nsDef);
1160 if (!
is_ns_used(
reinterpret_cast<xmlNodePtr
>(nd),
ns)) {
1170 xmlNodePtr current =
reinterpret_cast<xmlNodePtr
>(nd)->children;
1172 erase_unused_ns_defs(current);
1173 current = current->next;
1179 xmlChar* path(xmlGetNodePath(pimpl_->xmlnode_));
1181 std::string node_path(
reinterpret_cast<const char*
>(path));
1190 return xmlNodeIsText(pimpl_->xmlnode_) != 0;
1200 #ifdef NCBI_COMPILER_WORKSHOP
1213 return pimpl_->xmlnode_->children == 0;
1218 return iterator(pimpl_->xmlnode_->children);
1238 if (pimpl_->xmlnode_->parent ==
NULL)
1240 return pimpl_->xmlnode_->parent->type == XML_DOCUMENT_NODE;
1247 return iterator(pimpl_->xmlnode_->parent);
1260 xmlNodePtr found = find_element(name, pimpl_->xmlnode_->children, nspace);
1267 const ns *nspace)
const {
1268 xmlNodePtr found = find_element(name, pimpl_->xmlnode_->children, nspace);
1277 xmlNodePtr
n =
static_cast<xmlNodePtr
>(start.
get_raw_node());
1278 if ( (
n = find_element(name,
n, nspace)))
return iterator(
n);
1285 const ns *nspace)
const {
1286 xmlNodePtr
n =
static_cast<xmlNodePtr
>(start.
get_raw_node());
1293 xmlXPathContextPtr xpath_context(
1294 reinterpret_cast<xmlXPathContextPtr
>(
1295 create_xpath_context(expr)));
1296 xmlXPathObjectPtr object(
1297 reinterpret_cast<xmlXPathObjectPtr
>(
1300 xmlXPathFreeContext(xpath_context);
1302 switch (object->type) {
1308 return convert_to_nset(
object);
1318 xmlXPathContextPtr xpath_context(
1319 reinterpret_cast<xmlXPathContextPtr
>(
1320 create_xpath_context(expr)));
1321 xmlXPathObjectPtr object(
1322 reinterpret_cast<xmlXPathObjectPtr
>(
1325 xmlXPathFreeContext(xpath_context);
1327 switch (object->type) {
1329 case XPATH_XSLT_TREE:
1334 return convert_to_nset(
object);
1343 get_effective_namespaces(type_ns_only_non_default)));
1349 get_effective_namespaces(type_ns_only_non_default)));
1355 if (!pimpl_->xmlnode_)
1356 throw xml::exception(
"invalid node to get effective namespaces");
1359 xmlNsPtr * nsList = xmlGetNsList(pimpl_->xmlnode_->doc,
1361 xmlNsPtr * current = nsList;
1366 while (*current !=
NULL) {
1368 case type_ns_only_default:
1369 if ((*current)->prefix ==
NULL)
1370 nspaces.push_back(
ns(*current));
1372 case type_ns_only_non_default:
1373 if ((*current)->prefix !=
NULL)
1374 nspaces.push_back(
ns(*current));
1377 nspaces.push_back(
ns(*current));
1391 if (!pimpl_->xmlnode_ || !pimpl_->xmlnode_->doc)
1393 "(reference to document is not set)");
1395 xmlXPathContextPtr xpath_context(xmlXPathNewContext(
1396 pimpl_->xmlnode_->doc));
1397 if (!xpath_context) {
1398 const xmlError * last_error(xmlGetLastError());
1399 std::string message(
"cannot create xpath context");
1401 if (last_error && last_error->message)
1402 message +=
" : " +
std::string(last_error->message);
1407 for (ns_list_type::const_iterator k(nspaces.begin());
1408 k!=nspaces.end(); ++k) {
1409 const char* prefix(k->get_prefix());
1410 if (strlen(prefix) == 0) {
1413 if (xmlXPathRegisterNs(
1415 reinterpret_cast<const xmlChar*
>(prefix),
1416 reinterpret_cast<const xmlChar*
>(k->get_uri())) != 0) {
1417 const xmlError * last_error(xmlGetLastError());
1418 std::string message(
"cannot create xpath context "
1419 "(namespace registering error)");
1421 if (last_error && last_error->message)
1422 message +=
" : " +
std::string(last_error->message);
1424 xmlXPathFreeContext(xpath_context);
1428 xpath_context->node = pimpl_->xmlnode_;
1429 return xpath_context;
1436 xmlXPathObjectPtr object(
NULL);
1439 object = xmlXPathCompiledEval(
1440 reinterpret_cast<xmlXPathCompExprPtr
>(
1442 reinterpret_cast<xmlXPathContextPtr
>(
context));
1445 object = xmlXPathEvalExpression(
1446 reinterpret_cast<const xmlChar*
>(expr.
get_xpath()),
1447 reinterpret_cast<xmlXPathContextPtr
>(
context));
1450 const xmlError * last_error(xmlGetLastError());
1451 std::string message(
"error evaluating xpath expression");
1453 if (last_error && last_error->message)
1454 message +=
" : " +
std::string(last_error->message);
1456 xmlXPathFreeContext(
reinterpret_cast<xmlXPathContextPtr
>(
context));
1465 n.pimpl_->xmlnode_));
1474 n.pimpl_->xmlnode_));
1500 iterator to_remove(begin()), the_end(end());
1502 while ( (to_remove = find(name, to_remove)) != the_end) {
1504 to_remove = erase(to_remove);
1507 return removed_count;
1512 if (!pimpl_->xmlnode_->children)
1514 xmlFreeNodeList(pimpl_->xmlnode_->children);
1515 pimpl_->xmlnode_->children =
NULL;
1516 pimpl_->xmlnode_->last =
NULL;
1521 xmlNodePtr
i(pimpl_->xmlnode_->children),
next(0);
1522 std::vector<xmlNodePtr> node_list;
1527 if (
i->type == XML_ELEMENT_NODE &&
1529 reinterpret_cast<const xmlChar*
>(node_name)) == 0) {
1531 node_list.push_back(
i);
1537 if (node_list.empty())
return;
1539 std::sort(node_list.begin(), node_list.end(), compare_attr(attr_name));
1540 std::for_each(node_list.begin(), node_list.end(),
1541 insert_node(pimpl_->xmlnode_));
1546 xmlNodePtr
i(pimpl_->xmlnode_->children),
next(0);
1547 std::vector<xmlNodePtr> node_list;
1552 if (
i->type == XML_ELEMENT_NODE) {
1554 node_list.push_back(
i);
1560 if (node_list.empty())
return;
1563 std::for_each(node_list.begin(), node_list.end(),
1564 insert_node(pimpl_->xmlnode_));
1570 int compression_level =
flags & 0xFFFF;
1571 node2doc n2d(pimpl_->xmlnode_);
1572 xmlDocPtr doc = n2d.get_doc();
1576 doc->compression = compression_level;
1580 const char * enc =
NULL;
1581 if (pimpl_->xmlnode_->doc)
1582 enc = (
const char *)(pimpl_->xmlnode_->doc->encoding);
1585 enc, libxml2_options);
1588 xmlSaveDoc(ctxt, doc);
1609 node2doc n2d(pimpl_->xmlnode_);
1610 xmlDocPtr raw_doc = n2d.get_doc();
1617 format_option, node_sort_option);
1631 xmlXPathObjectPtr
object =
reinterpret_cast<xmlXPathObjectPtr
>(
1636 switch (object->type) {
1639 if (object->boolval == 0) content =
"false";
1640 else content =
"true";
1645 snprintf(
buffer, 64,
"%g", object->floatval);
1651 reinterpret_cast<const char*
>(object->stringval));
1655 "object type to be converted "
1660 xml::node new_node(
"xpath_scalar_result", content.c_str());
1664 xmlNodeSetPtr new_node_set = xmlXPathNodeSetCreate(
NULL);
1665 if (new_node_set ==
NULL)
1667 "converting xpath result");
1668 xmlXPathNodeSetAdd(new_node_set,
1673 object->type = XPATH_NODESET;
1674 object->nodesetval = new_node_set;
1675 object->boolval = 1;
1682 bool operator() (
const xmlNsPtr & lhs,
const xmlNsPtr & rhs)
const {
1683 if (lhs->prefix ==
NULL)
1685 if (lhs->prefix[0] ==
'\0')
1687 if (rhs->prefix ==
NULL)
1689 if (rhs->prefix[0] ==
'\0')
1691 return strcmp(
reinterpret_cast<const char *
>(lhs->prefix),
1692 reinterpret_cast<const char *
>(rhs->prefix)) < 0;
1698 std::list<xmlNsPtr> ns_defs;
1699 xmlNsPtr nsd = pimpl_->xmlnode_->nsDef;
1703 ns_defs.push_back(nsd);
1711 xmlNsPtr cur =
NULL;
1714 for (std::list<xmlNsPtr>::const_iterator k = ns_defs.begin();
1715 k != ns_defs.end(); ++k) {
1719 pimpl_->xmlnode_->nsDef = cur;
1734 node2doc n2d(
n.pimpl_->xmlnode_);
1735 xmlDocPtr doc = n2d.get_doc();
1739 const char * enc =
NULL;
1740 if (
n.pimpl_->xmlnode_->doc)
1741 enc = (
const char *)(
n.pimpl_->xmlnode_->doc->encoding);
1744 enc, libxml2_options);
1747 xmlSaveDoc(ctxt, doc);
This file defines the xml::ait_impl class.
This file contains the definition of the xml::attributes class.
Const Iterator class for accessing attribute pairs.
Iterator class for accessing attribute pairs.
The xml::attributes class is used to access all the attributes of one xml::node.
void insert(const char *name, const char *value, const ns *nspace=NULL)
Add an attribute to the attributes list.
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 save_to_string_canonical(std::string &str, canonicalization_option c14n_option, canonicalization_comments_option comments_option, canonicalization_format_option format_option, canonicalization_node_sort_option node_sort_option) const
Convert the XML document tree into XML text data and place it into the given string.
This exception class is thrown by xmlwrapp for all runtime XML-related errors along with the xml::par...
const char * get(void) const
The xml::node::const_iterator provides a way to access children nodes similar to a standard C++ conta...
void * get_raw_node(void) const
The xml::node::iterator provides a way to access children nodes similar to a standard C++ container.
void * get_raw_node(void) const
The xml::node_set class is used to store xpath query result set.
The xml::node class is used to hold information about one XML node.
void set_name(const char *name)
Set the name of this xml::node.
node_set convert_to_nset(void *) const
node_type get_type(void) const
Get this node's "type".
void * release_node_data(void)
void append_to_string(std::string &xml, save_option_flags flags=save_op_default) const
Convert the node and all its children into XML text and set the given string to that text.
ns_definition_adding_type
enum for policies of adding namespace definitions
void erase_namespace(void)
Remove the node namespace.
attributes::iterator find_attribute(const char *name, const ns *nspace=NULL)
Search for a node attribute.
bool is_text(void) const
Find out if this node is a text node or sometiming like a text node, CDATA for example.
const char * get_name(void) const
Get the name of this xml::node.
ns_list_type get_namespace_definitions(ns::ns_safety_type type=ns::type_safe_ns) const
Get the namespaces defined at this xml::node.
effective_ns_list_type
enum to specify what namespaces to include into the list of the node effective namespaces
iterator erase(const iterator &to_erase)
Erase the node that is pointed to by the given iterator.
void * evaluate_xpath_expression(const xml::xpath_expression &expr, void *context) const
ns add_namespace_definition(const ns &name_space, ns_definition_adding_type type)
Add namespace definition to the node.
void clear(void)
Erase all children nodes.
iterator parent(void)
Get an iterator that points at the parent of this node.
void erase_unused_ns_defs(void)
Erase unused namespace definitions.
void save_to_string_canonical(std::string &str, canonicalization_option c14n_option, canonicalization_comments_option comments_option, canonicalization_format_option format_option, canonicalization_node_sort_option node_sort_option) const
Convert the node and all its children into XML text and set the given string to that text.
void set_node_data(void *data)
node & assign(const node &other)
Copy another node object into this one.
ns set_namespace(const ns &name_space)
Set the node namespace.
ns_definition_erase_type
enum to specify how to remove namespace definitions
ns_list_type get_effective_namespaces(effective_ns_list_type which=type_ns_all) const
Provides a list of effective namespaces for the node.
node(void)
Construct a new blank xml::node.
bool empty(void) const
Find out if this node has any children.
void push_back(const node &child)
Add a child xml::node to this node.
iterator find(const char *name, const ns *nspace=NULL)
Find the first child node that has the given name and namespace.
void erase_duplicate_ns_defs(void)
Erase duplicate namespace definitions.
void * get_node_data(void) const
void erase_duplicate_ns_defs_single_node(void *nd, std::deque< ns_list_type > &defs)
void * create_xpath_context(const xml::xpath_expression &expr) const
node_type
enum for the different types of XML nodes
iterator replace(const iterator &old_node, const node &new_node)
Replace the node pointed to by the given iterator with another node.
iterator begin(void)
Get an iterator that points to the beginning of this node's children.
ns add_namespace_def(const char *uri, const char *prefix)
node * detached_copy(void) const
Create a copy of the node which is detached from the document.
std::string get_path(void) const
Get the node path.
virtual ~node(void)
Class destructor.
void save_to_string(std::string &xml, save_option_flags flags=save_op_default) const
Convert the node and all its children into XML text and set the given string to that text.
void set_content(const char *content)
Set the content of a node.
ns get_namespace(ns::ns_safety_type type=ns::type_safe_ns) const
Get the namespace of this xml::node.
node_set run_xpath_query(const xpath_expression &expr)
Run the given XPath query.
void * find_replacement_ns_def(std::deque< ns_list_type > &defs, void *ns)
void sort_namespace_definitions(void)
Sorts the namespace definitions in the node in place.
node & operator=(const node &other)
Make this node equal to some other node via assignment.
const char * get_content(void) const
Get the content for this text node.
void erase_namespace_definition(const char *prefix, ns_definition_erase_type how=type_ns_def_erase_if_not_used)
Remove the node namespace definition.
std::size_t size_type
size type
bool is_root(void) const
Find out if this node is a root one, i.e.
void set_raw_content(const char *raw_content)
Set the raw content of a node.
void add_namespace_definitions(const ns_list_type &name_spaces, ns_definition_adding_type type)
Add namespace definitions to the node.
ns lookup_namespace(const char *prefix, ns::ns_safety_type type=ns::type_safe_ns) const
Look up a namespace with the given prefix.
void swap(node &other)
Swap this node with another one.
iterator insert(const node &n)
Insert a new child node.
size_type size(void) const
Returns the number of childer this nodes has.
void sort_fo(impl::cbfo_node_compare &fo)
ns add_matched_namespace_def(void *libxml2RawNamespace, const char *uri, ns_definition_adding_type type)
void sort(const char *node_name, const char *attr_name)
Sort all the children nodes of this node using one of thier attributes.
iterator self(void)
Get an iterator that points back at this node.
xml::attributes & get_attributes(void)
Get the list of attributes.
The xml::ns class is used to access and handle namespaces of nodes and attributes.
ns_safety_type
Namespace object "safety".
const char * get_prefix(void) const
Get the namespace prefix.
const char * get_uri(void) const
Get the namespace URI.
bool is_safe(void) const
Check if the object is safe i.e.
ns(const char *prefix, const char *uri)
Create a new xml::ns object with the given prefix and URI.
bool is_void(void) const
If a node or an attribute has no namespace, then a namespace with empty prefix and empty URI is retur...
The xml::xpath_expression class is used to store xpath query string and optional XML namespaces.
void * get_compiled_expression() const
const char * get_xpath() const
Provide the xpath expression as a string.
const ns_list_type & get_namespaces() const
Provide the list of the registered XML namespaces.
compile_type get_compile_type() const
Provide the expression pre-compilation flag.
static xmlXPathObjectPtr evaluate_xpath_expression(xsltTransformContextPtr ctxt, const char *xpath_expression, xmlNodePtr node)
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
static const char * str(char *buf, int n)
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
This file contains the definition of the xml::document class.
This file contains the definition of the xml::exception class.
This file contains the definition of the xml::node class.
constexpr auto sort(_Init &&init)
int strcmp(const char *str1, const char *str2)
xmlNodePtr node_replace(xmlNodePtr old_node, xmlNodePtr new_node)
Replace a node with another one.
void erase_ns_definition(xmlNodePtr node, xmlNsPtr definition)
Erases namespace definition in the node.
xmlNsPtr lookup_default_ns_above(xmlNodePtr node)
Searches for a default namspace definition in the given node and above.
xmlNodePtr node_erase(xmlNodePtr to_erase)
Erase a node from the child list, and then free it from memory.
void update_children_default_ns(xmlNodePtr node, xmlNsPtr newns)
Replaces the node and its children default namespace with the given.
int save_to_string_cb(void *ctx, const char *buf, int len)
bool is_ns_used(xmlNodePtr node, xmlNsPtr ns)
Check if the node, attributes and children use the namespace.
void replace_ns(xmlNodePtr node, xmlNsPtr oldNs, xmlNsPtr newNs)
Replaces old namspace with a new one in nodes and attributes all the way down in the hierarchy.
int convert_to_libxml2_save_options(int options)
phantom_attr * find_default_prop(xmlNodePtr xmlnode, const char *name, const ns *nspace)
xmlAttrPtr find_prop(xmlNodePtr xmlnode, const char *name, const ns *nspace)
int save_to_stream_cb(void *ctx, const char *buf, int len)
xmlNodePtr node_insert(xmlNodePtr parent, xmlNodePtr before, xmlNodePtr to_add)
Insert a node somewhere in the child list of a parent node.
xmlNsPtr lookup_ns_definition(xmlNodePtr node, const char *prefix)
Searches for a namspace definition in the given node.
void invalidate_default_attr_iterators(xmlNodePtr xmlnode)
node_private_data * attach_node_private_data(void *)
int save_option_flags
Bitwise save options mask type and a compression level.
std::ostream & operator<<(std::ostream &stream, const document &doc)
std::vector< xml::ns > ns_list_type
type for holding XML namespaces
canonicalization_comments_option
@ save_op_default
Default is:
canonicalization_option
Canonicalization mode.
canonicalization_format_option
canonicalization_node_sort_option
Front end for a platform-specific configuration summary.
This file defines the xml::impl::node_iterator class for libxml2.
This file contains the definition of the xml::node manipulation functions.
XPath execution result set for XmlWrapp.
bool operator()(xmlNodePtr lhs, xmlNodePtr rhs)
node_cmp(cbfo_node_compare &cb)
struct attr_instance * attr_instances_
struct phantom_attr * phantom_attrs_
static bool node_ns_match(xmlNode *nd, const ns *nspace)
Helper struct for creating a xml::node of type_cdata.
Helper struct for creating a xml::node of type_pi.
Helper struct for creating a xml::node of type_text.
static const char * type_name(CS_INT value)
static CS_CONTEXT * context