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/>.
18 * This file was adapted from schema.cc by Fugro Intersite B.V./Tjalling Hattink
21 #include <libxml++/relaxngschema.h>
23 #include <libxml/tree.h>
24 #include <libxml/relaxng.h>
28 // This class holds an xmlRelaxNGParserCtxtPtr and releases it on
29 // destruction. This way, we make sure we don't leak it, not even
30 // when an exception is thrown.
31 class RelaxNGSchemaParserContextHolder
34 RelaxNGSchemaParserContextHolder(xmlRelaxNGParserCtxtPtr ctx): ctx_(ctx) {}
35 ~RelaxNGSchemaParserContextHolder() { if (ctx_) xmlRelaxNGFreeParserCtxt(ctx_); }
38 xmlRelaxNGParserCtxtPtr ctx_;
45 struct RelaxNGSchema::Impl
47 Impl() : schema(nullptr) {}
53 RelaxNGSchema::RelaxNGSchema()
58 RelaxNGSchema::RelaxNGSchema(_xmlRelaxNG* schema)
61 pimpl_->schema = schema;
64 RelaxNGSchema::RelaxNGSchema(const std::string& filename)
70 RelaxNGSchema::RelaxNGSchema(const Document* document)
73 parse_document(document);
76 RelaxNGSchema::~RelaxNGSchema()
81 void RelaxNGSchema::parse_file(const std::string& filename)
83 parse_context(xmlRelaxNGNewParserCtxt(filename.c_str()));
86 void RelaxNGSchema::parse_memory(const Glib::ustring& contents)
88 parse_context(xmlRelaxNGNewMemParserCtxt(contents.c_str(), contents.bytes()));
91 void RelaxNGSchema::parse_document(const Document* document)
94 throw parse_error("RelaxNGSchema::parse_document(): document must not be nullptr.");
96 // xmlRelaxNGNewDocParserCtxt() takes a copy of the xmlDoc.
97 parse_context(xmlRelaxNGNewDocParserCtxt(const_cast<xmlDoc*>(document->cobj())));
100 void RelaxNGSchema::parse_context(_xmlRelaxNGParserCtxt* context)
103 release_underlying();
106 throw parse_error("RelaxNGSchema::parse_context(): Could not create parser context.\n" + format_xml_error());
108 RelaxNGSchemaParserContextHolder holder(context);
110 pimpl_->schema = xmlRelaxNGParse(context);
112 throw parse_error("RelaxNGSchema::parse_context(): Schema could not be parsed.\n" + format_xml_error());
115 _xmlRelaxNG* RelaxNGSchema::cobj()
117 return pimpl_->schema;
120 const _xmlRelaxNG* RelaxNGSchema::cobj() const
122 return pimpl_->schema;
125 void RelaxNGSchema::release_underlying()
129 xmlRelaxNGFree(pimpl_->schema);
130 pimpl_->schema = nullptr;