1 /* Copyright (C) 2014 The libxml++ development team
3 * This file is part of libxml++.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 #include "libxml++/validators/xsdvalidator.h"
20 #include "libxml++/xsdschema.h"
22 #include <libxml/xmlschemas.h>
27 struct XsdValidator::Impl
29 Impl() : schema(nullptr), is_schema_owner(false), context(nullptr) {}
33 _xmlSchemaValidCtxt* context;
37 XsdValidator::XsdValidator()
42 XsdValidator::XsdValidator(const std::string& filename)
48 XsdValidator::XsdValidator(const Document* document)
51 parse_document(document);
54 XsdValidator::XsdValidator(XsdSchema* schema, bool take_ownership)
57 set_schema(schema, take_ownership);
60 XsdValidator::~XsdValidator()
65 void XsdValidator::parse_file(const std::string& filename)
67 set_schema(new XsdSchema(filename), true);
70 void XsdValidator::parse_memory(const Glib::ustring& contents)
72 std::unique_ptr<XsdSchema> schema(new XsdSchema());
73 schema->parse_memory(contents);
74 set_schema(schema.release(), true);
77 void XsdValidator::parse_document(const Document* document)
79 set_schema(new XsdSchema(document), true);
82 void XsdValidator::set_schema(XsdSchema* schema, bool take_ownership)
85 pimpl_->schema = schema;
86 pimpl_->is_schema_owner = take_ownership;
89 void XsdValidator::release_underlying()
93 xmlSchemaFreeValidCtxt(pimpl_->context);
94 pimpl_->context = nullptr;
99 if (pimpl_->is_schema_owner)
100 delete pimpl_->schema;
101 pimpl_->schema = nullptr;
104 SchemaValidatorBase::release_underlying();
107 XsdSchema* XsdValidator::get_schema()
109 return pimpl_->schema;
112 const XsdSchema* XsdValidator::get_schema() const
114 return pimpl_->schema;
117 XsdValidator::operator bool() const noexcept
119 return pimpl_->schema && pimpl_->schema->cobj();
123 void XsdValidator::initialize_context()
125 xmlSchemaSetValidErrors(pimpl_->context, &callback_validity_error, &callback_validity_warning, this);
126 SchemaValidatorBase::initialize_context();
130 void XsdValidator::validate(const Document* document)
133 throw internal_error("XsdValidator::validate(): document must not be 0.");
136 throw internal_error("XsdValidator::validate(): Must have a schema to validate document");
138 // A context is required at this stage only
139 if (!pimpl_->context)
140 pimpl_->context = xmlSchemaNewValidCtxt(pimpl_->schema->cobj());
142 if (!pimpl_->context)
143 throw internal_error("XsdValidator::validate(): Could not create validating context");
146 initialize_context();
148 const int res = xmlSchemaValidateDoc(pimpl_->context, const_cast<xmlDoc*>(document->cobj()));
151 check_for_exception();
153 auto error_str = format_xml_error();
154 if (error_str.empty())
155 error_str = "Error code from xmlSchemaValidateDoc(): " + Glib::ustring::format(res);
156 throw validity_error("Document failed XSD schema validation.\n" + error_str);
160 void XsdValidator::validate(const std::string& filename)
163 throw internal_error("XsdValidator::validate(): Must have a schema to validate file.");
165 // A context is required at this stage only
166 if (!pimpl_->context)
167 pimpl_->context = xmlSchemaNewValidCtxt(pimpl_->schema->cobj());
169 if (!pimpl_->context)
170 throw internal_error("XsdValidator::validate(): Could not create validating context");
173 initialize_context();
175 const int res = xmlSchemaValidateFile(pimpl_->context, filename.c_str(), 0);
178 check_for_exception();
180 auto error_str = format_xml_error();
181 if (error_str.empty())
182 error_str = "Error code from xmlSchemaValidateFile(): " + Glib::ustring::format(res);
183 throw validity_error("XML file failed XSD schema validation.\n" + error_str);