- Notifications
You must be signed in to change notification settings - Fork 337
/
Copy pathxml_functions.cpp
128 lines (108 loc) · 4.14 KB
/
xml_functions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0,
* as published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms, as
* designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include"base/xml_functions.h"
#include"base/log.h"
#include"base/string_utilities.h"
#include"base/file_utilities.h"
#include<libxml/HTMLparser.h>
#include<glib.h>
#include<stdexcept>
#include<vector>
DEFAULT_LOG_DOMAIN("XML Functions")
static void xmlErrorHandling(void *ctx, constchar *msg, ...) {
va_list args;
va_start(args, msg);
va_list args_copy;
va_copy(args_copy, args);
std::vector<char> buff(1 + std::vsnprintf(NULL, 0, msg, args_copy));
va_end(args_copy);
std::vsnprintf(buff.data(), buff.size(), msg, args);
va_end(args);
logError("LibXml: %s\n", buff.data());
}
xmlDocPtr base::xml::loadXMLDoc(const std::string &path) {
xmlSetGenericErrorFunc(nullptr, xmlErrorHandling);
if (!base::file_exists(path))
throwstd::runtime_error("unable to open XML file, doesn't exists: " + path);
xmlDocPtr doc = xmlParseFile(path.c_str());
if (doc == nullptr)
throwstd::runtime_error("unable to parse XML file " + path);
return doc;
}
xmlDocPtr base::xml::xmlParseFragment(const std::string &buff) {
returnxmlParseMemory(buff.data(), (int)buff.size());
}
xmlNodePtr base::xml::getXmlRoot(xmlDocPtr doc) {
auto cur = xmlDocGetRootElement(doc);
if (cur == NULL)
throwstd::runtime_error("Empty document\n");
return cur;
}
boolbase::xml::nameIs(xmlNodePtr node, const std::string &name) {
returnxmlStrcmp(node->name, (const xmlChar *)name.c_str()) == 0;
}
boolbase::xml::nameIs(xmlAttrPtr attrib, const std::string &name) {
returnxmlStrcmp(attrib->name, (const xmlChar *)name.c_str()) == 0;
}
voidbase::xml::getXMLDocMetainfo(xmlDocPtr doc, std::string &doctype, std::string &docversion) {
xmlNodePtr root = xmlDocGetRootElement(doc);
while (root) {
if (root->type == XML_ELEMENT_NODE) {
doctype = getProp(root, "document_type");
docversion = getProp(root, "version");
break;
}
root = root->next;
}
}
std::string base::xml::getProp(xmlNodePtr node, const std::string &name) {
xmlChar *prop = xmlGetProp(node, (xmlChar *)name.c_str());
std::string tmp = prop ? (char *)prop : "";
xmlFree(prop);
return tmp;
}
std::string base::xml::getContent(xmlNodePtr node) {
xmlChar *prop = xmlNodeGetContent(node);
std::string tmp = prop ? (char *)prop : "";
xmlFree(prop);
return tmp;
}
std::string base::xml::getContentRecursive(xmlNodePtr node) {
std::string result;
result = base::xml::getContent(node);
auto current = node->children;
while (current != nullptr) {
result += base::xml::getContent(current);
current = current->next;
}
return result;
}
std::string base::xml::encodeEntities(const std::string &input) {
int buffSize = (int)input.size() * 2 + 1;
std::vector<unsignedchar> buff(buffSize, '\0');
int outLen = buffSize - 1, inLen = (int)input.size();
htmlEncodeEntities(buff.data(), &outLen, (constunsignedchar *)(input.c_str()), &inLen, '"');
buff.erase(buff.begin() + outLen, buff.end());
returnstd::string(buff.begin(), buff.end());
}