2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 ////////////////////////////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_NS_XmlParser
19 /// \brief This file contains implementation of CXmlParser class.
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
25 ////////////////////////////////////////////////////////////////////////////////////////////////////
26 #include <native_service/ns_xmlparser_if.h>
29 #include "ns_xmlconfig_parser_frameworkunifiedlog.h"
31 ////////////////////////////////////////////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////////////////////////////////////////////
35 CXmlParser::CXmlParser(): m_pXmlDoc(NULL), m_cFileName(""), m_pRootNode(NULL) {
36 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
38 // for maintaining indentation
39 xmlKeepBlanksDefault(0); // LCOV_EXCL_BR_LINE 11: except branch
41 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
44 ////////////////////////////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////////////////////////////
48 CXmlParser::~CXmlParser() {
49 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
51 // clears the document structure
52 ClearDocument(); // LCOV_EXCL_BR_LINE 11: except branch
54 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
57 ////////////////////////////////////////////////////////////////////////////////////////////////
59 /// Parses the xml file and creates a document structure
60 ////////////////////////////////////////////////////////////////////////////////////////////////
61 EFrameworkunifiedStatus CXmlParser::ParseXml(std::string f_cFileName) {
62 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
63 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
65 // clears the document structure
66 ClearDocument(); // LCOV_EXCL_BR_LINE 11: except branch
68 m_cFileName = f_cFileName;
70 if (IsReadable(m_cFileName)) {
71 // create document object structure
72 m_pXmlDoc = xmlParseFile(m_cFileName.c_str());
74 if (NULL != m_pXmlDoc) {
75 // sets the root node in class
76 m_pRootNode.SetXmlNodePtr(xmlDocGetRootElement(m_pXmlDoc));
78 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Document not parsed successfully :: %s", f_cFileName.c_str()); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
79 l_eStatus = eFrameworkunifiedStatusNullPointer;
82 l_eStatus = eFrameworkunifiedStatusInvldParam;
83 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "File not exists :: %s", f_cFileName.c_str()); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
86 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
90 ////////////////////////////////////////////////////////////////////////////////////////////////
92 /// Creates a new xml document with f_cRootNodeName as root node
93 ////////////////////////////////////////////////////////////////////////////////////////////////
94 EFrameworkunifiedStatus CXmlParser::CreateNewXmlDoc(std::string f_cRootNodeName) {
95 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
96 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
98 xmlNodePtr l_pRootNodePtr = NULL;
100 // clears the document structure
103 if (0 < f_cRootNodeName.length()) {
104 // creates new document structure
105 m_pXmlDoc = xmlNewDoc((const xmlChar *)"1.0");
106 if (NULL != m_pXmlDoc) {
107 // create new node(root)
108 l_pRootNodePtr = xmlNewNode(NULL,
109 (const xmlChar *)f_cRootNodeName.c_str());
110 if (NULL != l_pRootNodePtr) {
111 // sets the root node in document structure
112 xmlDocSetRootElement(m_pXmlDoc, l_pRootNodePtr);
114 // sets the root node in class
115 m_pRootNode.SetXmlNodePtr(l_pRootNodePtr);
117 l_eStatus = eFrameworkunifiedStatusNullPointer;
118 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Error creating new root node"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
121 l_eStatus = eFrameworkunifiedStatusNullPointer;
122 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Unable to create new xml document structure"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
125 l_eStatus = eFrameworkunifiedStatusInvldParam;
126 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Invalid root node name :: %s", f_cRootNodeName.c_str()); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
129 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
133 ////////////////////////////////////////////////////////////////////////////////////////////////
135 /// Saves the document structure in an xml file
136 ////////////////////////////////////////////////////////////////////////////////////////////////
137 EFrameworkunifiedStatus CXmlParser::SaveXml(std::string f_cFileName) {
138 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
139 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
140 std::string l_cFileName = "";
142 // if user explicitly provides file name
143 if (0 < f_cFileName.length()) {
144 l_cFileName.assign(f_cFileName);
145 } else { // takes the file name from the CXmlParser object
146 l_cFileName.assign(m_cFileName);
149 if (NULL != m_pXmlDoc) {
150 if (IsReadable(l_cFileName)) {
151 // save the doc structure to the file
152 if (-1 == xmlSaveFormatFileEnc(l_cFileName.c_str(), m_pXmlDoc, "UTF-8", 1)) {
153 l_eStatus = eFrameworkunifiedStatusFail;
156 l_eStatus = eFrameworkunifiedStatusInvldParam;
157 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "File not exists :: %s", f_cFileName.c_str()); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
160 l_eStatus = eFrameworkunifiedStatusNullPointer;
161 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "m_pXmlDoc is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
165 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
169 ////////////////////////////////////////////////////////////////////////////////////////////////
171 /// Gets the root node object of xml
172 ////////////////////////////////////////////////////////////////////////////////////////////////
173 CXmlNode CXmlParser::GetRootNode() {
174 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
176 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
180 ////////////////////////////////////////////////////////////////////////////////////////////////
182 /// Adds the new node to the parent node
183 ////////////////////////////////////////////////////////////////////////////////////////////////
184 CXmlNode CXmlParser::AddNewNode(CXmlNode m_pParentNode, std::string f_cNewNodeName, std::string f_cContent) {
185 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
188 if (!m_pParentNode.IsNull()) {
189 l_pXmlNode = m_pParentNode.AddChildNode(f_cNewNodeName, f_cContent); // LCOV_EXCL_BR_LINE 11: except branch
192 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
196 ////////////////////////////////////////////////////////////////////////////////////////////////
198 /// Removes the node from the xml
199 ////////////////////////////////////////////////////////////////////////////////////////////////
200 EFrameworkunifiedStatus CXmlParser::RemoveNode(CXmlNode m_pNode) {
201 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
202 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
204 if (!m_pNode.IsNull()) {
205 xmlUnlinkNode(m_pNode.m_pXmlNodePtr);
206 xmlFreeNode(m_pNode.m_pXmlNodePtr);
208 l_eStatus = eFrameworkunifiedStatusNullPointer;
211 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
215 ////////////////////////////////////////////////////////////////////////////////////////////////
217 /// Finds the first matching node, by tag name or path
218 ////////////////////////////////////////////////////////////////////////////////////////////////
219 CXmlNode CXmlParser::FindNode(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
220 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
223 xmlXPathObjectPtr l_pXpathObj = GetNodeSet(f_cNodePath, f_pCurrentNode); // LCOV_EXCL_BR_LINE 11: except branch
225 if (NULL != l_pXpathObj) {
226 if (NULL != l_pXpathObj->nodesetval && 0 < l_pXpathObj->nodesetval->nodeNr) {
227 l_pXmlNode.SetXmlNodePtr(l_pXpathObj->nodesetval->nodeTab[0]); // LCOV_EXCL_BR_LINE 11: except branch
229 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "NodeSetVal is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
232 xmlXPathFreeObject(l_pXpathObj); // LCOV_EXCL_BR_LINE 11: except branch
234 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "xmlXPathObjectPtr is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
237 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
241 ////////////////////////////////////////////////////////////////////////////////////////////////
243 /// Finds all the matching node, by tag name or path
244 ////////////////////////////////////////////////////////////////////////////////////////////////
245 TNodeList CXmlParser::FindAllNodes(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
246 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
247 TNodeList l_pNodeList;
249 xmlXPathObjectPtr l_pXpathObj = GetNodeSet(f_cNodePath, f_pCurrentNode); // LCOV_EXCL_BR_LINE 11: except branch
251 if (NULL != l_pXpathObj) {
252 if (NULL != l_pXpathObj->nodesetval && 0 < l_pXpathObj->nodesetval->nodeNr) {
253 for (UI_8 l_uiSize = 0;
254 l_uiSize < l_pXpathObj->nodesetval->nodeNr;
256 if (NULL != l_pXpathObj->nodesetval->nodeTab[l_uiSize]) {
257 CXmlNode l_pNode(l_pXpathObj->nodesetval->nodeTab[l_uiSize]); // LCOV_EXCL_BR_LINE 11: except branch
258 l_pNodeList.push_back(l_pNode);
260 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "node pointer is NULL");
264 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "NodeSetVal is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
267 xmlXPathFreeObject(l_pXpathObj); // LCOV_EXCL_BR_LINE 11: except branch
269 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "xmlXPathObjectPtr is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
272 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
276 ////////////////////////////////////////////////////////////////////////////////////////////////
278 /// Gets the node set resulting from search of nodepath using XPath
279 ////////////////////////////////////////////////////////////////////////////////////////////////
280 xmlXPathObjectPtr CXmlParser::GetNodeSet(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
281 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
282 xmlXPathObjectPtr l_pXpathObj = NULL;
284 xmlXPathContextPtr l_pXpathCtx = NULL;
287 if (NULL != m_pXmlDoc) {
288 if (!f_pCurrentNode.IsNull()) {
289 l_pXmlNode = f_pCurrentNode;
292 // Create xpath evaluation context
293 l_pXpathCtx = xmlXPathNewContext(m_pXmlDoc); // LCOV_EXCL_BR_LINE 11: except branch
295 if (NULL != l_pXpathCtx) {
296 // set the current node in path context
297 l_pXpathCtx->node = l_pXmlNode.m_pXmlNodePtr;
299 // Evaluate xpath expression
300 l_pXpathObj = xmlXPathEvalExpression((const xmlChar *)f_cNodePath.c_str(), l_pXpathCtx); // LCOV_EXCL_BR_LINE 11: except branch
302 if (NULL == l_pXpathObj) {
303 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to evaluate nodepath :: \"%s\"", f_cNodePath.c_str()); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
306 // Cleanup of XPath data
307 xmlXPathFreeContext(l_pXpathCtx); // LCOV_EXCL_BR_LINE 11: except branch
309 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to create new XPath context"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
312 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "document object is NULL"); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
315 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
319 ////////////////////////////////////////////////////////////////////////////////////////////////
321 /// Clears the document structure and resets the root node
322 ////////////////////////////////////////////////////////////////////////////////////////////////
323 VOID CXmlParser::ClearDocument() {
324 if (NULL != m_pXmlDoc) {
326 xmlFreeDoc(m_pXmlDoc);
329 // free the global variables that may have been allocated by the parser
337 ////////////////////////////////////////////////////////////////////////////////////////////////
339 /// Checks whether the file exists or not
340 ////////////////////////////////////////////////////////////////////////////////////////////////
341 BOOL CXmlParser::IsReadable(const std::string &filename) {
342 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
343 BOOL l_bReadable = FALSE;
345 std::ifstream l_ifstream(filename.c_str());
347 if (l_ifstream.good()) {
349 l_ifstream.close(); // LCOV_EXCL_BR_LINE 11: except branch
352 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");