Torc  0.1
torclibxmlvalidator.cpp
Go to the documentation of this file.
1 /* Class TorcXmlValidator
2 *
3 * Copyright (C) Mark Kendall 2016-18
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 
20 // Qt
21 #include <QFile>
22 
23 // Torc
24 #include "torclogging.h"
25 #include "torclibxmlvalidator.h"
26 
27 // libxml2
28 #include <libxml/parser.h>
29 #include <libxml/valid.h>
30 #include <libxml/xmlschemas.h>
31 
32 TorcXmlValidator::TorcXmlValidator(const QString &XmlFile, const QString &XSDFile, bool Silent /*= false*/)
33  : m_xmlFile(XmlFile),
34  m_xsdFile(XSDFile),
35  m_xsdData(QByteArray()),
36  m_valid(false),
37  m_xsdDone(false),
38  m_silent(Silent)
39 {
40  Validate();
41 }
42 
43 TorcXmlValidator::TorcXmlValidator(const QString &XmlFile, const QByteArray &XSDData, bool Silent /*= false*/)
44  : m_xmlFile(XmlFile),
45  m_xsdFile(QStringLiteral("")),
46  m_xsdData(XSDData),
47  m_valid(false),
48  m_xsdDone(false),
49  m_silent(Silent)
50 {
51  Validate();
52 }
53 
54 void TorcXmlValidator::HandleMessage(void *ctx, const char *format, ...)
55 {
56  bool silent = false;
57 
58  TorcXmlValidator* owner = static_cast<TorcXmlValidator*>(ctx);
59  if (owner)
60  silent = owner->GetSilent();
61 
62  if (silent)
63  return;
64 
65  char *error;
66  va_list args;
67  va_start(args, format);
68  bool ok = vasprintf(&error, format, args) >= 0;
69  va_end(args);
70  if (ok)
71  {
72  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Libxml error: %1").arg(error));
73  free(error);
74  }
75 }
76 
77 
79 {
80  xmlSetStructuredErrorFunc(nullptr, nullptr);
81  xmlSetGenericErrorFunc(this, HandleMessage);
82  xmlThrDefSetStructuredErrorFunc(nullptr, nullptr);
83  xmlThrDefSetGenericErrorFunc(this, HandleMessage);
84 
85  xmlSchemaParserCtxtPtr parsercontext = nullptr;
86 
87  if (!m_xsdFile.isEmpty())
88  {
89  parsercontext = xmlSchemaNewParserCtxt(m_xsdFile.toLocal8Bit().constData());
90  }
91  else if (!m_xsdData.isEmpty())
92  {
93  parsercontext = xmlSchemaNewMemParserCtxt(m_xsdData.constData(), m_xsdData.size());
94  }
95 
96  if (!parsercontext)
97  {
98  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Failed to create parser context for XSD"));
99  return;
100  }
101 
102  xmlSchemaPtr schema = xmlSchemaParse(parsercontext);
103 
104  if (!schema)
105  {
106  xmlSchemaFreeParserCtxt(parsercontext);
107  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Failed to parse XSD"));
108  return;
109  }
110 
111  xmlSchemaValidCtxtPtr validcontext = xmlSchemaNewValidCtxt(schema);
112 
113  if (!validcontext)
114  {
115  xmlSchemaFree(schema);
116  xmlSchemaFreeParserCtxt(parsercontext);
117  LOG(VB_GENERAL, LOG_ERR, QStringLiteral("Could not create XSD schema validation context"));
118  return;
119  }
120 
121  if (!m_silent)
122  LOG(VB_GENERAL, LOG_INFO, QStringLiteral("XSD loaded and validated"));
123 
124  m_xsdDone = true;
125 
126  xmlDocPtr xmldocumentptr = xmlParseFile(m_xmlFile.toLocal8Bit().constData());
127  int result = xmlSchemaValidateDoc(validcontext, xmldocumentptr);
128 
129  if (result == 0)
130  m_valid = true;
131 
132  xmlFreeDoc(xmldocumentptr);
133  xmlSchemaFreeValidCtxt(validcontext);
134  xmlSchemaFree(schema);
135  xmlSchemaFreeParserCtxt(parsercontext);
136 }
137 
139 {
140  return m_silent;
141 }
142 
144 {
145  return m_valid;
146 }
bool GetSilent(void) const
static void HandleMessage(void *ctx, const char *format,...)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: torclogging.h:20
bool Validated(void) const
TorcXmlValidator(const QString &XmlFile, const QString &XSDFile, bool Silent=false)