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++/xsdschema.h>
21 #include <libxml/tree.h>
22 #include <libxml/xmlschemas.h>
26 // This class holds an xmlSchemaParserCtxtPtr and releases it on
27 // destruction. This way, we make sure we don't leak it, not even
28 // when an exception is thrown.
29 class XsdSchemaParserContextHolder
32 XsdSchemaParserContextHolder(xmlSchemaParserCtxtPtr ctx): ctx_(ctx) {}
33 ~XsdSchemaParserContextHolder() { if (ctx_) xmlSchemaFreeParserCtxt(ctx_); }
36 xmlSchemaParserCtxtPtr ctx_;
43 struct XsdSchema::Impl
45 Impl() : schema(nullptr), document(nullptr) {}
52 XsdSchema::XsdSchema()
57 XsdSchema::XsdSchema(_xmlSchema* schema)
60 pimpl_->schema = schema;
63 XsdSchema::XsdSchema(const std::string& filename)
69 XsdSchema::XsdSchema(const Document* document)
72 parse_document(document);
75 XsdSchema::~XsdSchema()
80 void XsdSchema::parse_file(const std::string& filename)
84 parse_context(xmlSchemaNewParserCtxt(filename.c_str()));
87 void XsdSchema::parse_memory(const Glib::ustring& contents)
91 parse_context(xmlSchemaNewMemParserCtxt(contents.c_str(), contents.bytes()));
94 void XsdSchema::parse_document(const Document* document)
97 throw parse_error("XsdSchema::parse_document(): document must not be nullptr.");
100 release_underlying();
102 // xmlSchemaParse() may modify the document. Take a copy.
103 pimpl_->document = xmlCopyDoc(const_cast<xmlDoc*>(document->cobj()), true); // recursive copy
104 if (!pimpl_->document)
105 throw parse_error("XsdSchema::parse_document(): Could not copy the document.\n" + format_xml_error());
107 parse_context(xmlSchemaNewDocParserCtxt(pimpl_->document));
110 void XsdSchema::parse_context(_xmlSchemaParserCtxt* context)
113 throw parse_error("XsdSchema::parse_context(): Could not create parser context.\n" + format_xml_error());
115 XsdSchemaParserContextHolder holder(context);
117 pimpl_->schema = xmlSchemaParse(context);
120 release_underlying();
121 throw parse_error("XsdSchema::parse_context(): Schema could not be parsed.\n" + format_xml_error());
125 _xmlSchema* XsdSchema::cobj()
127 return pimpl_->schema;
130 const _xmlSchema* XsdSchema::cobj() const
132 return pimpl_->schema;
135 void XsdSchema::release_underlying()
139 xmlSchemaFree(pimpl_->schema);
140 pimpl_->schema = nullptr;
143 if (pimpl_->document)
145 xmlFreeDoc(pimpl_->document);
146 pimpl_->document = nullptr;