ChimeraTK-ControlSystemAdapter-OPCUAAdapter  04.00.01
xml_file_handler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ChimeraTKs ControlSystem-OPC-UA-Adapter.
3  *
4  * ChimeraTKs ControlSystem-OPC-UA-Adapter is free software: you can
5  * redistribute it and/or modify it under the terms of the Lesser GNU
6  * General Public License as published by the Free Software Foundation,
7  * either version 3 of the License, or (at your option) any later version.
8  *
9  * ChimeraTKs ControlSystem-OPC-UA-Adapter is distributed in the hope
10  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
11  * implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * See the Lesser GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Foobar. If not, see https://www.gnu.org/licenses/lgpl.html
16  *
17  * Copyright (c) 2016 Chris Iatrou <Chris_Paul.Iatrou@tu-dresden.de>
18  * Copyright (c) 2016 Julian Rahm <Julian.Rahm@tu-dresden.de>
19  * Copyright (c) 2023 Andreas Ebner <Andreas.Ebner@iosb.fraunhofer.de>
20  */
21 
22 #include "xml_file_handler.h"
23 
24 #include "open62541/plugin/log_stdout.h"
25 #include <libxml2/libxml/tree.h>
26 #include <libxml2/libxml/xpath.h>
27 #include <libxml2/libxml/xpathInternals.h>
28 
29 #include <boost/algorithm/string.hpp>
30 #include <boost/tokenizer.hpp>
31 
32 #include <iostream>
33 
34 using namespace std;
35 
36 namespace ChimeraTK {
37  xml_file_handler::xml_file_handler(const std::string& filePath) {
38  if(!this->createDoc(filePath)) {
39  throw logic_error(
40  std::string("Failed to parse ") + filePath + (". Check if mapping file exsists and is well formated."));
41  }
42  }
43 
44  std::vector<xmlNodePtr> xml_file_handler::getNodesByName(xmlNodePtr startNode, const std::string& nodeName) {
45  std::vector<xmlNodePtr> nodeVector;
46  while(startNode != nullptr) {
47  if((!xmlStrcmp(startNode->name, (const xmlChar*)nodeName.c_str()))) {
48  nodeVector.push_back(startNode);
49  }
50  startNode = startNode->next;
51  }
52 
53  return nodeVector;
54  }
55 
56  xmlXPathObjectPtr xml_file_handler::getNodeSet(const std::string& xPathString) {
57  auto* xpath = (xmlChar*)xPathString.c_str();
58  xmlXPathContextPtr context;
59  xmlXPathObjectPtr result;
60 
61  if(!isDocSetted()) {
62  return nullptr;
63  }
64  context = xmlXPathNewContext(this->doc);
65  if(context == nullptr) {
66  return nullptr;
67  }
68  if(xmlXPathRegisterNs(context, (xmlChar*)"csa",
69  (xmlChar*)"https://github.com/ChimeraTK/ControlSystemAdapter-OPC-UA-Adapter") != 0) {
70  UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
71  "Failed to register xml namespace: https://github.com/ChimeraTK/ControlSystemAdapter-OPC-UA-Adapter");
72  return nullptr;
73  }
74 
75  result = xmlXPathEvalExpression(xpath, context);
76  xmlXPathFreeContext(context);
77  if(result == nullptr) {
78  return nullptr;
79  }
80  if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
81  xmlXPathFreeObject(result);
82  return nullptr;
83  }
84  return result;
85  }
86 
87  bool xml_file_handler::isDocSetted() {
88  if(this->doc != nullptr) {
89  return true;
90  }
91  return false;
92  }
93 
94  bool xml_file_handler::createDoc(const std::string& filePath) {
95  if(filePath.empty()) {
96  this->doc = nullptr;
97  return false;
98  }
99 
100  this->doc = xmlParseFile(filePath.c_str());
101 
102  if(this->doc == nullptr) {
103  UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Document not parsed successfully.");
104  return false;
105  }
106 
107  return true;
108  }
109 
110  std::vector<std::string> xml_file_handler::parseVariablePath(
111  const std::string& variablePath, const std::string& seperator) {
112  std::vector<std::string> pathList;
113  boost::char_separator<char> sep(seperator.c_str());
114  boost::tokenizer<boost::char_separator<char>> tokens(variablePath, sep);
115 
116  for(const auto& t : tokens) {
117  pathList.push_back(t);
118  }
119  return pathList;
120  }
121 
122  std::string xml_file_handler::getAttributeValueFromNode(xmlNode* node, const std::string& attributeName) {
123  xmlAttrPtr attr = xmlHasProp(node, (xmlChar*)attributeName.c_str());
124  if(attr != nullptr) {
125  std::string merker = (std::string)((char*)attr->children->content);
126  return merker;
127  }
128  return "";
129  }
130 
131  std::string xml_file_handler::getContentFromNode(xmlNode* node) {
132  if(node != nullptr) {
133  xmlChar* content = xmlNodeGetContent(node->xmlChildrenNode);
134  if(content != nullptr) {
135  std::string maker = (std::string)((char*)content);
136  xmlFree(content);
137  boost::trim(maker);
138  return maker;
139  }
140  }
141  return "";
142  }
143 
144  xml_file_handler::~xml_file_handler() {
145  xmlFreeDoc(this->doc);
146  xmlCleanupParser();
147  }
148 } // namespace ChimeraTK
xml_file_handler.h
ChimeraTK
Definition: csa_additionalvariable.h:28