ChimeraTK-ControlSystemAdapter-OPCUAAdapter 04.00.05
Loading...
Searching...
No Matches
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
26#include <libxml2/libxml/tree.h>
27#include <libxml2/libxml/xpath.h>
28#include <libxml2/libxml/xpathInternals.h>
29
30#include <boost/algorithm/string.hpp>
31#include <boost/tokenizer.hpp>
32
33#include <iostream>
34
35using namespace std;
36
37namespace ChimeraTK {
38 xml_file_handler::xml_file_handler(const std::string& filePath) {
39 if(!this->createDoc(filePath)) {
40 throw logic_error(
41 std::string("Failed to parse ") + filePath + (". Check if mapping file exsists and is well formated."));
42 }
43 }
44
45 std::vector<xmlNodePtr> xml_file_handler::getNodesByName(xmlNodePtr startNode, const std::string& nodeName) {
46 std::vector<xmlNodePtr> nodeVector;
47 while(startNode != nullptr) {
48 if((!xmlStrcmp(startNode->name, (const xmlChar*)nodeName.c_str()))) {
49 nodeVector.push_back(startNode);
50 }
51 startNode = startNode->next;
52 }
53
54 return nodeVector;
55 }
56
57 xmlXPathObjectPtr xml_file_handler::getNodeSet(const std::string& xPathString) {
58 auto* xpath = (xmlChar*)xPathString.c_str();
59 xmlXPathContextPtr context;
60 xmlXPathObjectPtr result;
61
62 if(!isDocSetted()) {
63 return nullptr;
64 }
65 context = xmlXPathNewContext(this->doc);
66 if(context == nullptr) {
67 return nullptr;
68 }
69 if(xmlXPathRegisterNs(context, (xmlChar*)"csa",
70 (xmlChar*)"https://github.com/ChimeraTK/ControlSystemAdapter-OPC-UA-Adapter") != 0) {
71 UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
72 "Failed to register xml namespace: https://github.com/ChimeraTK/ControlSystemAdapter-OPC-UA-Adapter");
73 return nullptr;
74 }
75
76 result = xmlXPathEvalExpression(xpath, context);
77 xmlXPathFreeContext(context);
78 if(result == nullptr) {
79 return nullptr;
80 }
81 if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
82 xmlXPathFreeObject(result);
83 return nullptr;
84 }
85 return result;
86 }
87
89 if(this->doc != nullptr) {
90 return true;
91 }
92 return false;
93 }
94
95 bool xml_file_handler::createDoc(const std::string& filePath) {
96 if(filePath.empty()) {
97 this->doc = nullptr;
98 return false;
99 }
100
101 this->doc = xmlParseFile(filePath.c_str());
102
103 if(this->doc == nullptr) {
104 UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Document not parsed successfully.");
105 return false;
106 }
107
108 return true;
109 }
110
111 std::vector<std::string> xml_file_handler::parseVariablePath(
112 const std::string& variablePath, const std::string& seperator) {
113 std::vector<std::string> pathList;
114 boost::char_separator<char> sep(seperator.c_str());
115 boost::tokenizer<boost::char_separator<char>> tokens(variablePath, sep);
116
117 for(const auto& t : tokens) {
118 pathList.push_back(t);
119 }
120 return pathList;
121 }
122
123 std::string xml_file_handler::getAttributeValueFromNode(xmlNode* node, const std::string& attributeName) {
124 xmlAttrPtr attr = xmlHasProp(node, (xmlChar*)attributeName.c_str());
125 if(attr != nullptr) {
126 std::string merker = (std::string)((char*)attr->children->content);
127 return merker;
128 }
129 return "";
130 }
131
132 std::string xml_file_handler::getContentFromNode(xmlNode* node) {
133 if(node != nullptr) {
134 xmlChar* content = xmlNodeGetContent(node->xmlChildrenNode);
135 if(content != nullptr) {
136 std::string maker = (std::string)((char*)content);
137 xmlFree(content);
138 boost::trim(maker);
139 return maker;
140 }
141 }
142 return "";
143 }
144
146 xmlFreeDoc(this->doc);
147 xmlCleanupParser();
148 }
149} // namespace ChimeraTK
xml_file_handler(const std::string &filePath)
The constructor of the class creates a doc pointer depending on the file path.
static std::vector< xmlNodePtr > getNodesByName(xmlNodePtr startNode, const std::string &nodeName)
This methode return a list of all nodes with the given name nodeName starting by the given startNode.
bool createDoc(const std::string &filePath)
This methode set a document pointer to the file it ist given by the file path.
xmlXPathObjectPtr getNodeSet(const std::string &xPathString)
This methode return a pointer of a xPath element depending of the given xPathString.
~xml_file_handler()
Destructor of the class, frees the document and clean the parser.
static std::string getContentFromNode(xmlNode *node)
This methode returns the value between a xml tag.
static std::vector< std::string > parseVariablePath(const std::string &variablePath, const std::string &seperator="/")
This methode splitt a given string bey the given seperators.
static std::string getAttributeValueFromNode(xmlNode *node, const std::string &attributeName)
This methode returns a value of the given attribute from the given node you want to know.
bool isDocSetted()
This Methode check if a document is currently setted.