YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
XMLReader.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7
18
20
21#include <yarp/os/LogStream.h>
22#include <yarp/os/Property.h>
23
24#include <algorithm>
25#include <iterator>
26#include <memory>
27#include <sstream>
28#include <string>
29#include <tinyxml.h>
30#include <vector>
31
32namespace {
33YARP_LOG_COMPONENT(YRI_XMLDREADER, "yarp.yri.XMLReader")
34}
35
36#define SYNTAX_ERROR(line) yCError(YRI_XMLDREADER) << "Syntax error while loading" << curr_filename << "at line" << line << "."
37#define SYNTAX_WARNING(line) yCWarning(YRI_XMLDREADER) << "Invalid syntax while loading" << curr_filename << "at line" << line << "."
38
39// BUG in TinyXML, see
40// https://sourceforge.net/tracker/?func=detail&aid=3567726&group_id=13559&atid=113559
41// When this bug is fixed upstream we can enable this
42#define TINYXML_UNSIGNED_INT_BUG 0
43
56
57
62
67
69{
70 mPriv->verbose = verb;
71}
72
74{
75 mPriv->enable_deprecated = enab;
76}
77
79 const yarp::os::Searchable& config)
80{
81 std::string filename = fileName;
82#if defined(_WIN32)
83 std::replace(filename.begin(), filename.end(), '/', '\\');
84#endif
85 std::string curr_filename = fileName;
86 std::string path = filename.substr(0, filename.rfind(yarp::conf::filesystem::preferred_separator));
87
88 yCDebug(YRI_XMLDREADER) << "Reading file" << filename.c_str();
89 auto doc = std::make_unique< TiXmlDocument>(TiXmlDocument(filename.c_str()));
90 if (!doc->LoadFile()) {
91 SYNTAX_ERROR(doc->ErrorRow()) << doc->ErrorDesc();
93 }
94
95 if (!doc->RootElement()) {
96 SYNTAX_ERROR(doc->Row()) << "No root element.";
98 }
99
101
102 for (TiXmlNode* childNode = doc->FirstChild(); childNode != nullptr; childNode = childNode->NextSibling()) {
103 if (childNode->Type() == TiXmlNode::TINYXML_UNKNOWN) {
104 if (dtd.parse(childNode->ToUnknown(), curr_filename)) {
105 break;
106 }
107 }
108 }
109
110 if (!dtd.valid()) {
111 SYNTAX_WARNING(doc->Row()) << "No DTD found. Assuming version yarprobotinterfaceV3.0";
112 dtd.setDefault();
114 }
115
117 SYNTAX_WARNING(doc->Row()) << "Expected document of type" << DocTypeToString(RobotInterfaceDTD::DocTypeRobot)
118 << ". Found" << DocTypeToString(dtd.type);
119 }
120
121 if (dtd.majorVersion == 1) {
122 yCError(YRI_XMLDREADER) << "DTD V1.x has been deprecated. Please update your configuration files to DTD v3.x";
123 if (mPriv->enable_deprecated) {
124 yCWarning(YRI_XMLDREADER) << "yarprobotinterface: using DEPRECATED xml parser for DTD v1.x";
126 return mPriv->mReader->getRobotFromFile(filename, config, mPriv->verbose);
127 }
128
129 yCError(YRI_XMLDREADER,"Invalid DTD version, execution stopped.");
131
132 }
133 if (dtd.majorVersion == 3) {
134 yCDebug(YRI_XMLDREADER) << "yarprobotinterface: using xml parser for DTD v3.x";
136 return mPriv->mReader->getRobotFromFile(filename, config, mPriv->verbose);
137 }
138
139 //ERROR HERE
140 yCError(YRI_XMLDREADER,"Invalid DTD version. Unable to choose parser for DTD.major: %d", dtd.majorVersion);
142}
143
145 const yarp::os::Searchable& config)
146{
147 std::string curr_filename = " XML runtime string ";
148 std::unique_ptr<TiXmlDocument> doc = std::make_unique<TiXmlDocument>();
149 if (!doc->Parse(xmlString.data())) {
150 SYNTAX_ERROR(doc->ErrorRow()) << doc->ErrorDesc();
152 }
153 if (!doc->RootElement()) {
154 SYNTAX_ERROR(doc->Row()) << "No root element.";
156 }
157
159
160 for (TiXmlNode* childNode = doc->FirstChild(); childNode != nullptr; childNode = childNode->NextSibling()) {
161 if (childNode->Type() == TiXmlNode::TINYXML_UNKNOWN) {
162 std::string curr_filename = " XML runtime string ";
163 if (dtd.parse(childNode->ToUnknown(), curr_filename)) {
164 break;
165 }
166 }
167 }
168
169 if (!dtd.valid()) {
170 SYNTAX_WARNING(doc->Row()) << "No DTD found. Assuming version yarprobotinterfaceV3.0";
171 dtd.setDefault();
173 }
174
176 SYNTAX_WARNING(doc->Row()) << "Expected document of type" << DocTypeToString(RobotInterfaceDTD::DocTypeRobot)
177 << ". Found" << DocTypeToString(dtd.type);
178 }
179
180 if (dtd.majorVersion == 1) {
181 yCError(YRI_XMLDREADER) << "DTD V1.x has been deprecated. Please update your configuration files to DTD v3.x";
182 if (mPriv->enable_deprecated) {
183 yCWarning(YRI_XMLDREADER) << "yarprobotinterface: using DEPRECATED xml parser for DTD v1.x";
185 return mPriv->mReader->getRobotFromString(xmlString, config, mPriv->verbose);
186 } else {
187 yCError(YRI_XMLDREADER,"Invalid DTD version, execution stopped.");
189 }
190 } else if (dtd.majorVersion == 3) {
191 yCDebug(YRI_XMLDREADER) << "yarprobotinterface: using xml parser for DTD v3.x";
193 return mPriv->mReader->getRobotFromString(xmlString, config, mPriv->verbose);
194 }
195
196 //ERROR HERE
197 yCError(YRI_XMLDREADER,"Invalid DTD version. Unable to choose parser for DTD.major: %d", dtd.majorVersion);
199}
#define SYNTAX_ERROR(line)
#define SYNTAX_WARNING(line)
A base class for nested structures that can be searched.
Definition Searchable.h:31
bool parse(TiXmlUnknown *unknownNode, const std::string &curr_filename)
Result of the parsing of yarp::robotinterface::XMLReader.
Definition XMLReader.h:26
static XMLReaderResult ParsingFailed()
Definition XMLReader.h:28
yarp::robotinterface::impl::XMLReaderFileVx * mReader
Definition XMLReader.cpp:54
XMLReaderResult getRobotFromFile(const std::string &filename, const yarp::os::Searchable &config=yarp::os::Property())
Parse the XML description of a robotinterface from a file.
Definition XMLReader.cpp:78
void setEnableDeprecated(bool enab)
Definition XMLReader.cpp:73
void setVerbose(bool verbose)
Definition XMLReader.cpp:68
XMLReaderResult getRobotFromString(const std::string &filename, const yarp::os::Searchable &config=yarp::os::Property())
Parse the XML description of a robotinterface from a string.
yarp::robotinterface::XMLReaderResult getRobotFromString(const std::string &xmlString, const yarp::os::Searchable &config, bool verbose=false) override
yarp::robotinterface::XMLReaderResult getRobotFromFile(const std::string &filename, const yarp::os::Searchable &config, bool verbose=false) override
yarp::robotinterface::XMLReaderResult getRobotFromString(const std::string &xmlString, const yarp::os::Searchable &config, bool verbose=false) override
yarp::robotinterface::XMLReaderResult getRobotFromFile(const std::string &filename, const yarp::os::Searchable &config, bool verbose=false) override
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
static constexpr value_type preferred_separator
Definition filesystem.h:21
std::string DocTypeToString(RobotInterfaceDTD::DocType doctype)