[libxml++] Add XsdSchema and XsdValidator. Deprecate Schema and SchemaValidator



commit dd71d6319e43229899c6a8146071b5c4a67ed265
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Oct 16 12:54:36 2014 +0200

    Add XsdSchema and XsdValidator. Deprecate Schema and SchemaValidator
    
    * configure.ac: Add MM_ARG_DISABLE_DEPRECATED_API([LIBXMLXX]).
    * Makefile.am: Add new files.
    * libxml++config.h.in: Add LIBXMLXX_DISABLE_DEPRECATED.
    * libxml++/libxml++.h: Add new header files.
    * libxml++/schema.[cc|h]:
    * libxml++/validators/schemavalidator.[cc|h]: Deprecate the whole files.
    * examples/schemavalidation/main.cc: Add test of XsdValidator.
    * libxml++/schemabase.[cc|h]:
    * libxml++/xsdschema.[cc|h]:
    * libxml++/validators/schemavalidatorbase.[cc|h]:
    * libxml++/validators/xsdvalidator.[cc|h]: New files. Bug #737712.

 Makefile.am                                |   14 ++-
 configure.ac                               |    5 +
 examples/schemavalidation/main.cc          |   42 ++++---
 libxml++/libxml++.h                        |    4 +-
 libxml++/schema.cc                         |    5 +
 libxml++/schema.h                          |   26 ++++-
 libxml++/schemabase.cc                     |   32 +++++
 libxml++/schemabase.h                      |   67 ++++++++++
 libxml++/validators/schemavalidator.cc     |    6 +-
 libxml++/validators/schemavalidator.h      |   20 +++-
 libxml++/validators/schemavalidatorbase.cc |   44 +++++++
 libxml++/validators/schemavalidatorbase.h  |  104 +++++++++++++++
 libxml++/validators/xsdvalidator.cc        |  187 ++++++++++++++++++++++++++++
 libxml++/validators/xsdvalidator.h         |  151 ++++++++++++++++++++++
 libxml++/xsdschema.cc                      |  150 ++++++++++++++++++++++
 libxml++/xsdschema.h                       |  104 +++++++++++++++
 libxml++config.h.in                        |    3 +
 17 files changed, 937 insertions(+), 27 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 03c8406..2168a32 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,9 @@ h_root_sources_public = libxml++/libxml++.h \
        libxml++/dtd.h \
        libxml++/keepblanks.h \
        libxml++/noncopyable.h \
-       libxml++/schema.h
+       libxml++/schema.h \
+       libxml++/schemabase.h \
+       libxml++/xsdschema.h
 h_exceptions_sources_public = libxml++/exceptions/exception.h \
        libxml++/exceptions/parse_error.h \
        libxml++/exceptions/validity_error.h \
@@ -53,7 +55,9 @@ h_parsers_sources_public = libxml++/parsers/parser.h \
        libxml++/parsers/textreader.h
 h_validators_sources_public = libxml++/validators/dtdvalidator.h \
        libxml++/validators/schemavalidator.h \
-       libxml++/validators/validator.h
+       libxml++/validators/schemavalidatorbase.h \
+       libxml++/validators/validator.h \
+       libxml++/validators/xsdvalidator.h
 h_sources_public = $(h_root_sources_public) \
        $(h_exceptions_sources_public) \
        $(h_io_sources_public) \
@@ -69,6 +73,8 @@ cc_sources = libxml++/attribute.cc \
        libxml++/keepblanks.cc \
        libxml++/noncopyable.cc \
        libxml++/schema.cc \
+       libxml++/schemabase.cc \
+       libxml++/xsdschema.cc \
        libxml++/exceptions/exception.cc \
        libxml++/exceptions/parse_error.cc \
        libxml++/exceptions/validity_error.cc \
@@ -94,7 +100,9 @@ cc_sources = libxml++/attribute.cc \
        libxml++/parsers/textreader.cc \
        libxml++/validators/dtdvalidator.cc \
        libxml++/validators/schemavalidator.cc \
-       libxml++/validators/validator.cc
+       libxml++/validators/schemavalidatorbase.cc \
+       libxml++/validators/validator.cc \
+       libxml++/validators/xsdvalidator.cc
 
 library_includedir = $(includedir)/libxml++-$(LIBXMLXX_API_VERSION)/libxml++
 library_exceptions_includedir = $(library_includedir)/exceptions
diff --git a/configure.ac b/configure.ac
index 44176ec..c256efe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,10 +39,14 @@ MM_ARG_WITH_TAGFILE_DOC([libstdc++.tag], [mm-common-libstdc++])
 MM_ARG_WITH_TAGFILE_DOC([libsigc++-2.0.tag], [sigc++-2.0])
 MM_ARG_WITH_TAGFILE_DOC([glibmm-2.4.tag], [glibmm-2.4])
 
+# Evaluate the --enable-warnings=level option.
 MM_ARG_ENABLE_WARNINGS([LIBXMLXX_WXXFLAGS],
         [-Wall],
         [-pedantic -Wall -Wextra -Wno-long-long])
 
+# Offer the ability to omit some API from the library.
+MM_ARG_DISABLE_DEPRECATED_API([LIBXMLXX])
+
 AC_PATH_PROG([XMLLINT], [xmllint], [xmllint])
 AC_ARG_VAR([XMLLINT], [path to xmllint utility])
 AC_PATH_PROGS([DB2LATEX], [db2latex docbook2latex], [db2latex])
@@ -60,6 +64,7 @@ AC_CONFIG_FILES([Makefile
         MSVC_Net2010/libxml++/libxml++.rc
         libxml++-2.6.pc])
 
+# Copy the generated configuration headers into the MSVC project directories.
 AC_CONFIG_COMMANDS([MSVC_Net2005/libxml++/libxml++config.h],
         [cp -f libxml++config.h MSVC_Net2005/libxml++/libxml++config.h])
 AC_CONFIG_COMMANDS([MSVC_Net2008/libxml++/libxml++config.h],
diff --git a/examples/schemavalidation/main.cc b/examples/schemavalidation/main.cc
index 1857bd1..9792a8c 100644
--- a/examples/schemavalidation/main.cc
+++ b/examples/schemavalidation/main.cc
@@ -1,5 +1,3 @@
-// -*- C++ -*-
-
 /* main.cc
  *
  * Copyright (C) 2002 The libxml++ development team
@@ -19,14 +17,13 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 #include <libxml++/libxml++.h>
 #include <iostream>
-#include <stdlib.h>
+#include <cstdlib>
 
 int main(int argc, char* argv[])
 {
@@ -34,34 +31,46 @@ int main(int argc, char* argv[])
   // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions.
   std::locale::global(std::locale(""));
 
-  std::string schemafilepath("example.xsd"),
-              docfilepath("example.xml");
+  std::string docfilepath("example.xml");
+  std::string xsdschemafilepath("example.xsd");
 
-  if(argc!=1 && argc!=3)
+  if (argc != 1 && argc != 3)
   {
-    std::cout << "usage : " << argv[0] << " [document schema]" << std::endl;
+    std::cout << "usage : " << argv[0] << " [document schema.xsd]" << std::endl;
     return EXIT_FAILURE;
   }
 
-  if(argc == 3)
+  if (argc == 3)
   {
     docfilepath = argv[1];
-    schemafilepath = argv[2];
+    xsdschemafilepath = argv[2];
   }
 
+  Glib::ustring phase;
   try
   {
-    xmlpp::SchemaValidator validator(schemafilepath);
-    Glib::ustring phase;
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+    phase = "XML"; // XSD schema, old validator class
+    xmlpp::SchemaValidator schemavalidator(xsdschemafilepath);
+#endif // LIBXMLXX_DISABLE_DEPRECATED
+
+    phase = "XSD";
+    xmlpp::XsdValidator xsdvalidator(xsdschemafilepath);
 
     try
     {
       phase = "parsing";
       xmlpp::DomParser parser(docfilepath);
 
-      phase = "validating";
-      validator.validate( parser.get_document() );
-      std::cout << "Valid document" << std::endl;
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+      phase = "XML validating";
+      schemavalidator.validate(parser.get_document());
+      std::cout << "Valid document, SchemaValidator" << std::endl;
+#endif // LIBXMLXX_DISABLE_DEPRECATED
+
+      phase = "XSD validating";
+      xsdvalidator.validate(parser.get_document());
+      std::cout << "Valid document, XsdValidator" << std::endl;
     }
     catch (const xmlpp::exception& ex)
     {
@@ -72,10 +81,9 @@ int main(int argc, char* argv[])
   }
   catch (const xmlpp::exception& ex)
   {
-    std::cerr << "Error parsing the schema" << std::endl;
+    std::cerr << "Error parsing the " << phase << " schema" << std::endl;
     std::cerr << ex.what() << std::endl;
     return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
 }
-
diff --git a/libxml++/libxml++.h b/libxml++/libxml++.h
index 91c2dd0..18b1ef9 100644
--- a/libxml++/libxml++.h
+++ b/libxml++/libxml++.h
@@ -27,7 +27,7 @@
  *
  * Include the libxml++ header:
  * @code
- * #include <libxml++.h>
+ * #include <libxml++/libxml++.h>
  * @endcode
  * (You may include individual headers, such as libxml++/document.h instead.)
  *
@@ -66,8 +66,10 @@
 #include <libxml++/attributedeclaration.h>
 #include <libxml++/attributenode.h>
 #include <libxml++/document.h>
+#include <libxml++/xsdschema.h>
 #include <libxml++/validators/validator.h>
 #include <libxml++/validators/dtdvalidator.h>
 #include <libxml++/validators/schemavalidator.h>
+#include <libxml++/validators/xsdvalidator.h>
 
 #endif //__LIBXMLCPP_H
diff --git a/libxml++/schema.cc b/libxml++/schema.cc
index a1e6351..8708ba9 100644
--- a/libxml++/schema.cc
+++ b/libxml++/schema.cc
@@ -4,6 +4,10 @@
  * included with libxml++ as the file COPYING.
  */
 
+#include <libxml++config.h> // LIBXMLXX_DISABLE_DEPRECATED
+
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+
 #include <libxml++/schema.h>
 
 #include <libxml/tree.h>
@@ -124,3 +128,4 @@ const _xmlSchema* Schema::cobj() const
 }
 
 } //namespace xmlpp
+#endif // LIBXMLXX_DISABLE_DEPRECATED
diff --git a/libxml++/schema.h b/libxml++/schema.h
index 9e9c648..63a6e4f 100644
--- a/libxml++/schema.h
+++ b/libxml++/schema.h
@@ -12,11 +12,13 @@
 #include <list>
 #include <map>
 
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" {
   struct _xmlSchema;
 }
-#endif //DOXYGEN_SHOULD_SKIP_THIS4
+#endif //DOXYGEN_SHOULD_SKIP_THIS
 
 namespace xmlpp
 {
@@ -24,11 +26,14 @@ namespace xmlpp
 /** Represents an XML Schema.
  *
  * @newin{2,24}
+ *
+ * @deprecated Use XsdSchema instead.
  */
 class Schema : NonCopyable
 {
 public:
   /** Create a schema from the underlying libxml schema element.
+   * @deprecated Use XsdSchema instead.
    */
   explicit Schema(_xmlSchema* schema);
 
@@ -38,6 +43,7 @@ public:
    *   the schema is deleted or another document is set.
    * @throws xmlpp::parse_error
    * @throws xmlpp::internal_error If an empty schema document can't be created.
+   * @deprecated Use XsdSchema instead.
    */
   explicit Schema(Document* document = 0, bool embed = false);
   ~Schema();
@@ -49,27 +55,40 @@ public:
    * @param embed If true, the document will be deleted when the schema is deleted or another document is 
set.
    * @throws xmlpp::parse_error
    * @throws xmlpp::internal_error If an empty schema document can't be created.
+   * @deprecated Use XsdSchema::parse_document() instead.
    */
   virtual void set_document(Document* document = 0, bool embed = false);
 
+  /** @deprecated There is no replacement.
+   */
   Glib::ustring get_name() const;
+  /** @deprecated There is no replacement.
+   */
   Glib::ustring get_target_namespace() const;
+  /** @deprecated There is no replacement.
+   */
   Glib::ustring get_version() const;
 
   /** Get the schema document.
    * @returns A pointer to the schema document, or <tt>0</tt> if none exists.
+   * @deprecated There is no replacement.
    */
   Document* get_document();
 
   /** Get the schema document.
    * @returns A pointer to the schema document, or <tt>0</tt> if none exists.
+   * @deprecated There is no replacement.
    */
   const Document* get_document() const;
   
-  /** Access the underlying libxml implementation. */
+  /** Access the underlying libxml implementation.
+   * @deprecated Use XsdSchema::cobj() instead.
+   */
   _xmlSchema* cobj();
 
-  /** Access the underlying libxml implementation. */
+  /** Access the underlying libxml implementation.
+   * @deprecated Use XsdSchema::cobj() instead.
+   */
   const _xmlSchema* cobj() const;
 
 protected:
@@ -84,4 +103,5 @@ private:
 
 } // namespace xmlpp
 
+#endif // LIBXMLXX_DISABLE_DEPRECATED
 #endif //__LIBXMLPP_SCHEMA_H
diff --git a/libxml++/schemabase.cc b/libxml++/schemabase.cc
new file mode 100644
index 0000000..02eb660
--- /dev/null
+++ b/libxml++/schemabase.cc
@@ -0,0 +1,32 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libxml++/schemabase.h>
+
+namespace xmlpp
+{
+
+SchemaBase::SchemaBase()
+{
+}
+
+SchemaBase::~SchemaBase()
+{
+}
+
+} //namespace xmlpp
diff --git a/libxml++/schemabase.h b/libxml++/schemabase.h
new file mode 100644
index 0000000..b09fc65
--- /dev/null
+++ b/libxml++/schemabase.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_SCHEMABASE_H
+#define __LIBXMLPP_SCHEMABASE_H
+
+#include <libxml++/noncopyable.h>
+
+namespace Glib
+{
+class ustring;
+}
+
+namespace xmlpp
+{
+class Document;
+
+/** Base class for schemas, used for validation of XML files.
+ *
+ * @newin{2,38}
+ */
+class SchemaBase : NonCopyable
+{
+public:
+  SchemaBase();
+  virtual ~SchemaBase();
+
+  /** Parse a schema definition file.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_file(const Glib::ustring& filename) = 0;
+
+  /** Parse a schema definition from a string.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param contents The schema definition as a string.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_memory(const Glib::ustring& contents) = 0;
+
+  /** Parse a schema definition from a document.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_document(const Document* document) = 0;
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_SCHEMABASE_H
diff --git a/libxml++/validators/schemavalidator.cc b/libxml++/validators/schemavalidator.cc
index f16ec55..8c678db 100644
--- a/libxml++/validators/schemavalidator.cc
+++ b/libxml++/validators/schemavalidator.cc
@@ -5,6 +5,10 @@
  * included with libxml++ as the file COPYING.
  */
 
+#include <libxml++config.h> // LIBXMLXX_DISABLE_DEPRECATED
+
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+
 #include "libxml++/validators/schemavalidator.h"
 #include "libxml++/schema.h"
 
@@ -225,4 +229,4 @@ bool SchemaValidator::validate(const Glib::ustring& file)
 }
 
 } // namespace xmlpp
-
+#endif // LIBXMLXX_DISABLE_DEPRECATED
diff --git a/libxml++/validators/schemavalidator.h b/libxml++/validators/schemavalidator.h
index a740090..134e0b1 100644
--- a/libxml++/validators/schemavalidator.h
+++ b/libxml++/validators/schemavalidator.h
@@ -12,18 +12,22 @@
 #include <libxml++/schema.h>
 #include <libxml++/document.h>
 
+#ifndef LIBXMLXX_DISABLE_DEPRECATED
+
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" {
   struct _xmlSchemaParserCtxt;
   struct _xmlSchemaValidCtxt;
 }
-#endif //DOXYGEN_SHOULD_SKIP_THIS4
+#endif //DOXYGEN_SHOULD_SKIP_THIS
 
 namespace xmlpp {
 
 /** XML Schema Validator.
  *
  * @newin{2,24}
+ *
+ * @deprecated Use XsdValidator instead.
  */
 class SchemaValidator : public Validator
 {
@@ -33,6 +37,7 @@ public:
   /** Create a validator and parse a schema definition file immediately.
    * @param file The URL of the schema.
    * @throws xmlpp::parse_error
+   * @deprecated Use XsdValidator instead.
    */
   explicit SchemaValidator(const Glib::ustring& file);
 
@@ -40,6 +45,7 @@ public:
    * @param document A preparsed document tree, containing the schema definition.
    * @note The document may be modified during the parsing process.
    * @throws xmlpp::parse_error
+   * @deprecated Use XsdValidator instead.
    */
   explicit SchemaValidator(Document& document);
 
@@ -49,6 +55,7 @@ public:
    *        guarantee that the schema exists as long as the validator keeps a
    *        pointer to it. The caller is responsible for deleting the schema
    *        when it's no longer needed.
+   * @deprecated Use XsdValidator instead.
    */
   explicit SchemaValidator(Schema* schema);
 
@@ -59,6 +66,7 @@ public:
    * (deleted if the validator owns the schema).
    * @param filename The URL of the schema.
    * @throws xmlpp::parse_error
+   * @deprecated Use XsdValidator::parse_file() instead.
    */
   virtual void parse_file(const Glib::ustring& filename);
 
@@ -67,6 +75,7 @@ public:
    * (deleted if the validator owns the schema).
    * @param contents The schema definition as a string.
    * @throws xmlpp::parse_error
+   * @deprecated Use XsdValidator::parse_memory() instead.
    */
   virtual void parse_memory(const Glib::ustring& contents);
 
@@ -76,6 +85,7 @@ public:
    * @param document A preparsed document tree, containing the schema definition.
    * @note The document may be modified during the parsing process.
    * @throws xmlpp::parse_error
+   * @deprecated Use XsdValidator::parse_document() instead.
    */
   virtual void parse_document(Document& document);
 
@@ -87,20 +97,24 @@ public:
    *        guarantee that the schema exists as long as the validator keeps a
    *        pointer to it. The caller is responsible for deleting the schema
    *        when it's no longer needed.
+   * @deprecated Use XsdValidator::set_schema() instead.
    */
   virtual void set_schema(Schema* schema);
 
   /** Test whether a schema has been parsed.
+   * @deprecated Use XsdValidator::operator BoolExpr() instead.
    */
   operator bool() const;
 
   /** Get the parsed schema.
    * @returns A pointer to the parsed schema, or <tt>0</tt>.
+   * @deprecated Use XsdValidator::get_schema() instead.
    */
   Schema* get_schema();
 
   /** Get the parsed schema.
    * @returns A pointer to the parsed schema, or <tt>0</tt>.
+   * @deprecated Use XsdValidator::get_schema() instead.
    */
   const Schema* get_schema() const;
 
@@ -109,6 +123,7 @@ public:
    * @returns Whether the document is valid.
    * @throws xmlpp::internal_error
    * @throws xmlpp::validity_error
+   * @deprecated Use XsdValidator::validate(const Document*) instead.
    */
   bool validate(const Document* doc);
 
@@ -117,6 +132,7 @@ public:
    * @returns Whether the document is valid.
    * @throws xmlpp::internal_error
    * @throws xmlpp::validity_error
+   * @deprecated Use XsdValidator::validate(const Glib::ustring&) instead.
    */
   bool validate(const Glib::ustring& file);
 
@@ -132,5 +148,5 @@ protected:
 
 } // namespace xmlpp
 
+#endif // LIBXMLXX_DISABLE_DEPRECATED
 #endif //__LIBXMLPP_VALIDATOR_SCHEMAVALIDATOR_H
-
diff --git a/libxml++/validators/schemavalidatorbase.cc b/libxml++/validators/schemavalidatorbase.cc
new file mode 100644
index 0000000..04aa74c
--- /dev/null
+++ b/libxml++/validators/schemavalidatorbase.cc
@@ -0,0 +1,44 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libxml++/validators/schemavalidatorbase.h"
+#include "libxml++/schemabase.h"
+
+namespace xmlpp
+{
+
+SchemaValidatorBase::SchemaValidatorBase()
+{
+}
+
+SchemaValidatorBase::~SchemaValidatorBase()
+{
+  release_underlying();
+}
+
+void SchemaValidatorBase::release_underlying()
+{
+  Validator::release_underlying();
+}
+
+void SchemaValidatorBase::initialize_valid()
+{
+  Validator::initialize_valid();
+}
+
+} // namespace xmlpp
diff --git a/libxml++/validators/schemavalidatorbase.h b/libxml++/validators/schemavalidatorbase.h
new file mode 100644
index 0000000..a96d061
--- /dev/null
+++ b/libxml++/validators/schemavalidatorbase.h
@@ -0,0 +1,104 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_VALIDATOR_SCHEMAVALIDATORBASE_H
+#define __LIBXMLPP_VALIDATOR_SCHEMAVALIDATORBASE_H
+
+#include <libxml++/validators/validator.h>
+#include <memory> // std::auto_ptr
+
+namespace Glib
+{
+class ustring;
+}
+
+namespace xmlpp
+{
+class Document;
+
+/** Base class for schema validators.
+ *
+ * @newin{2,38}
+ */
+class SchemaValidatorBase : public Validator
+{
+public:
+  SchemaValidatorBase();
+  virtual ~SchemaValidatorBase();
+
+  /** Parse a schema definition file.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_file(const Glib::ustring& filename) = 0;
+
+  /** Parse a schema definition from a string.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param contents The schema definition as a string.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_memory(const Glib::ustring& contents) = 0;
+
+  /** Parse a schema definition from a document.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_document(const Document* document) = 0;
+
+  /** This typedef is just to make it more obvious that
+   * our operator const void* should be used like operator bool().
+   */
+  typedef const void* BoolExpr;
+
+  /** Test whether a schema has been parsed.
+   * For instance
+   * @code
+   * if (validator)
+   *   do_something();
+   * @endcode
+   */
+  virtual operator BoolExpr() const = 0;
+
+  /** Validate a document, using a previously parsed schema.
+   * @param document Pointer to the document.
+   * @throws xmlpp::internal_error
+   * @throws xmlpp::validity_error
+   */
+  virtual void validate(const Document* document) = 0;
+
+  /** Validate an XML file, using a previously parsed schema.
+   * @param filename The URL of the XML file.
+   * @throws xmlpp::internal_error
+   * @throws xmlpp::parse_error
+   * @throws xmlpp::validity_error
+   */
+  virtual void validate(const Glib::ustring& filename) = 0;
+
+protected:
+  virtual void initialize_valid();
+  virtual void release_underlying();
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_VALIDATOR_SCHEMAVALIDATORBASE_H
diff --git a/libxml++/validators/xsdvalidator.cc b/libxml++/validators/xsdvalidator.cc
new file mode 100644
index 0000000..f213438
--- /dev/null
+++ b/libxml++/validators/xsdvalidator.cc
@@ -0,0 +1,187 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libxml++/validators/xsdvalidator.h"
+#include "libxml++/xsdschema.h"
+
+#include <libxml/xmlschemas.h>
+
+namespace xmlpp
+{
+
+struct XsdValidator::Impl
+{
+  Impl() : schema(0), is_schema_owner(false), context(0) {}
+
+  XsdSchema* schema;
+  bool is_schema_owner;
+  _xmlSchemaValidCtxt* context;
+};
+
+
+XsdValidator::XsdValidator()
+: pimpl_(new Impl)
+{
+}
+
+XsdValidator::XsdValidator(const Glib::ustring& filename)
+: pimpl_(new Impl)
+{
+  parse_file(filename);
+}
+
+XsdValidator::XsdValidator(const Document* document)
+: pimpl_(new Impl)
+{
+  parse_document(document);
+}
+
+XsdValidator::XsdValidator(XsdSchema* schema, bool take_ownership)
+: pimpl_(new Impl)
+{
+  set_schema(schema, take_ownership);
+}
+
+XsdValidator::~XsdValidator()
+{
+  release_underlying();
+}
+
+void XsdValidator::parse_file(const Glib::ustring& filename)
+{
+  set_schema(new XsdSchema(filename), true);
+}
+
+void XsdValidator::parse_memory(const Glib::ustring& contents)
+{
+  std::auto_ptr<XsdSchema> schema(new XsdSchema());
+  schema->parse_memory(contents);
+  set_schema(schema.release(), true);
+}
+
+void XsdValidator::parse_document(const Document* document)
+{
+  set_schema(new XsdSchema(document), true);
+}
+
+void XsdValidator::set_schema(XsdSchema* schema, bool take_ownership)
+{
+  release_underlying();
+  pimpl_->schema = schema;
+  pimpl_->is_schema_owner = take_ownership;
+}
+
+void XsdValidator::release_underlying()
+{
+  if (pimpl_->context)
+  {
+    xmlSchemaFreeValidCtxt(pimpl_->context);
+    pimpl_->context = 0;
+  }
+
+  if (pimpl_->schema)
+  {
+    if (pimpl_->is_schema_owner)
+      delete pimpl_->schema;
+    pimpl_->schema = 0;
+  }
+
+  SchemaValidatorBase::release_underlying();
+}
+
+XsdSchema* XsdValidator::get_schema()
+{
+  return pimpl_->schema;
+}
+
+const XsdSchema* XsdValidator::get_schema() const
+{
+  return pimpl_->schema;
+}
+
+XsdValidator::operator const void*() const
+{
+  return reinterpret_cast<const void*>(pimpl_->schema && pimpl_->schema->cobj());
+}
+
+
+void XsdValidator::initialize_valid()
+{
+  xmlSchemaSetValidErrors(pimpl_->context, &callback_validity_error, &callback_validity_warning, this);
+  SchemaValidatorBase::initialize_valid();
+}
+
+
+void XsdValidator::validate(const Document* document)
+{
+  if (!document)
+    throw internal_error("XsdValidator::validate(): document must not be 0.");
+
+  if (!*this)
+    throw internal_error("XsdValidator::validate(): Must have a schema to validate document");
+
+  // A context is required at this stage only
+  if (!pimpl_->context)
+    pimpl_->context = xmlSchemaNewValidCtxt(pimpl_->schema->cobj());
+
+  if (!pimpl_->context)
+    throw internal_error("XsdValidator::validate(): Could not create validating context");
+
+  xmlResetLastError();
+  initialize_valid();
+
+  const int res = xmlSchemaValidateDoc(pimpl_->context, const_cast<xmlDoc*>(document->cobj()));
+  if (res != 0)
+  {
+    check_for_exception();
+
+    Glib::ustring error_str = format_xml_error();
+    if (error_str.empty())
+      error_str = "Error code from xmlSchemaValidateDoc(): " + Glib::ustring::format(res);
+    throw validity_error("Document failed XSD schema validation.\n" + error_str);
+  }
+}
+
+void XsdValidator::validate(const Glib::ustring& filename)
+{
+  if (!*this)
+    throw internal_error("XsdValidator::validate(): Must have a schema to validate file.");
+
+  // A context is required at this stage only
+  if (!pimpl_->context)
+    pimpl_->context = xmlSchemaNewValidCtxt(pimpl_->schema->cobj());
+
+  if (!pimpl_->context)
+    throw internal_error("XsdValidator::validate(): Could not create validating context");
+
+  xmlResetLastError();
+  initialize_valid();
+
+  const int res = xmlSchemaValidateFile(pimpl_->context, filename.c_str(), 0);
+  if (res != 0)
+  {
+    check_for_exception();
+
+    Glib::ustring error_str = format_xml_error();
+    if (error_str.empty())
+      error_str = "Error code from xmlSchemaValidateFile(): " + Glib::ustring::format(res);
+    throw validity_error("XML file failed XSD schema validation.\n" + error_str);
+  }
+}
+
+} // namespace xmlpp
diff --git a/libxml++/validators/xsdvalidator.h b/libxml++/validators/xsdvalidator.h
new file mode 100644
index 0000000..573626b
--- /dev/null
+++ b/libxml++/validators/xsdvalidator.h
@@ -0,0 +1,151 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_VALIDATOR_XSDVALIDATOR_H
+#define __LIBXMLPP_VALIDATOR_XSDVALIDATOR_H
+
+#include <libxml++/validators/schemavalidatorbase.h>
+#include <memory> // std::auto_ptr
+
+namespace Glib
+{
+class ustring;
+}
+
+namespace xmlpp
+{
+class Document;
+class XsdSchema;
+
+/** XSD schema validator.
+ * XSD = XML %Schema Definition, a.k.a. XML %Schema or W3C XML %Schema
+ *
+ * @newin{2,38}
+ */
+class XsdValidator : public SchemaValidatorBase
+{
+public:
+  XsdValidator();
+
+  /** Create a validator and parse a schema definition file.
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  explicit XsdValidator(const Glib::ustring& filename);
+
+  /** Create a validator and parse a schema definition document.
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  explicit XsdValidator(const Document* document);
+
+  /** Create a validator.
+   * @param schema A pointer to the schema to use when validating XML documents.
+   * @param take_ownership If <tt>true</tt>, the validator takes ownership of
+   *        the schema. The caller must not delete it.<br>
+   *        If <tt>false</tt>, the validator does not take ownership of the schema.
+   *        The caller must guarantee that the schema exists as long as the
+   *        validator keeps a pointer to it. The caller is responsible for
+   *        deleting the schema when it's no longer needed.
+   */
+  explicit XsdValidator(XsdSchema* schema, bool take_ownership);
+
+  virtual ~XsdValidator();
+
+  /** Parse a schema definition file.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_file(const Glib::ustring& filename);
+
+  /** Parse a schema definition from a string.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param contents The schema definition as a string.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_memory(const Glib::ustring& contents);
+
+  /** Parse a schema definition from a document.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_document(const Document* document);
+
+  /** Set a schema.
+   * If the validator already contains a schema, that schema is released
+   * (deleted if the validator owns the schema).
+   * @param schema A pointer to the schema to use when validating XML documents.
+   * @param take_ownership If <tt>true</tt>, the validator takes ownership of
+   *        the schema. The caller must not delete it.<br>
+   *        If <tt>false</tt>, the validator does not take ownership of the schema.
+   *        The caller must guarantee that the schema exists as long as the
+   *        validator keeps a pointer to it. The caller is responsible for
+   *        deleting the schema when it's no longer needed.
+   */
+  void set_schema(XsdSchema* schema, bool take_ownership);
+
+  /** Test whether a schema has been parsed.
+   * For instance
+   * @code
+   * if (xsd_validator)
+   *   do_something();
+   * @endcode
+   */
+  virtual operator BoolExpr() const;
+
+  /** Get the schema.
+   * @returns A pointer to the schema, or <tt>0</tt>.
+   */
+  XsdSchema* get_schema();
+
+  /** Get the schema.
+   * @returns A pointer to the schema, or <tt>0</tt>.
+   */
+  const XsdSchema* get_schema() const;
+
+  /** Validate a document, using a previously parsed schema.
+   * @param document Pointer to the document.
+   * @throws xmlpp::internal_error
+   * @throws xmlpp::validity_error
+   */
+  virtual void validate(const Document* document);
+
+  /** Validate an XML file, using a previously parsed schema.
+   * @param filename The URL of the XML file.
+   * @throws xmlpp::internal_error
+   * @throws xmlpp::validity_error
+   */
+  virtual void validate(const Glib::ustring& filename);
+
+protected:
+  virtual void initialize_valid();
+  virtual void release_underlying();
+
+private:
+  struct Impl;
+  std::auto_ptr<Impl> pimpl_;
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_VALIDATOR_XSDVALIDATOR_H
diff --git a/libxml++/xsdschema.cc b/libxml++/xsdschema.cc
new file mode 100644
index 0000000..be7671d
--- /dev/null
+++ b/libxml++/xsdschema.cc
@@ -0,0 +1,150 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libxml++/xsdschema.h>
+
+#include <libxml/tree.h>
+#include <libxml/xmlschemas.h>
+
+namespace
+{
+  // This class holds an xmlSchemaParserCtxtPtr and releases it on
+  // destruction. This way, we make sure we don't leak it, not even
+  // when an exception is thrown.
+  class XsdSchemaParserContextHolder
+  {
+  public:
+    XsdSchemaParserContextHolder(xmlSchemaParserCtxtPtr ctx): ctx_(ctx) {}
+    ~XsdSchemaParserContextHolder() { if (ctx_) xmlSchemaFreeParserCtxt(ctx_); }
+
+  private:
+    xmlSchemaParserCtxtPtr ctx_;
+  };
+}
+
+namespace xmlpp
+{
+
+struct XsdSchema::Impl
+{
+  Impl() : schema(0), document(0) {}
+
+  _xmlSchema* schema;
+  _xmlDoc* document;
+};
+
+  
+XsdSchema::XsdSchema()
+: pimpl_(new Impl)
+{
+}
+
+XsdSchema::XsdSchema(_xmlSchema* schema)
+: pimpl_(new Impl)
+{
+  pimpl_->schema = schema;
+}
+
+XsdSchema::XsdSchema(const Glib::ustring& filename)
+: pimpl_(new Impl)
+{
+  parse_file(filename);
+}
+
+XsdSchema::XsdSchema(const Document* document)
+: pimpl_(new Impl)
+{
+  parse_document(document);
+}
+
+XsdSchema::~XsdSchema()
+{
+  release_underlying();
+}
+
+void XsdSchema::parse_file(const Glib::ustring& filename)
+{
+  xmlResetLastError();
+  release_underlying();
+  parse_context(xmlSchemaNewParserCtxt(filename.c_str()));
+}
+
+void XsdSchema::parse_memory(const Glib::ustring& contents)
+{
+  xmlResetLastError();
+  release_underlying();
+  parse_context(xmlSchemaNewMemParserCtxt(contents.c_str(), contents.bytes()));
+}
+
+void XsdSchema::parse_document(const Document* document)
+{
+  if (!document)
+    throw parse_error("XsdSchema::parse_document(): document must not be 0.");
+
+  xmlResetLastError();
+  release_underlying();
+
+  // xmlSchemaParse() may modify the document. Take a copy.
+  pimpl_->document = xmlCopyDoc(const_cast<xmlDoc*>(document->cobj()), true); // recursive copy
+  if (!pimpl_->document)
+    throw parse_error("XsdSchema::parse_document(): Could not copy the document.\n" + format_xml_error());
+
+  parse_context(xmlSchemaNewDocParserCtxt(pimpl_->document));
+}
+
+void XsdSchema::parse_context(_xmlSchemaParserCtxt* context)
+{
+  if (!context)
+    throw parse_error("XsdSchema::parse_context(): Could not create parser context.\n" + format_xml_error());
+  
+  XsdSchemaParserContextHolder holder(context);
+
+  pimpl_->schema = xmlSchemaParse(context);
+  if (!pimpl_->schema)
+  {
+    release_underlying();
+    throw parse_error("XsdSchema::parse_context(): Schema could not be parsed.\n" + format_xml_error());
+  }
+}
+
+_xmlSchema* XsdSchema::cobj()
+{
+  return pimpl_->schema;
+}
+
+const _xmlSchema* XsdSchema::cobj() const
+{
+  return pimpl_->schema;
+}
+
+void XsdSchema::release_underlying()
+{
+  if (pimpl_->schema)
+  {
+    xmlSchemaFree(pimpl_->schema);
+    pimpl_->schema = 0;
+  }
+
+  if (pimpl_->document)
+  {
+    xmlFreeDoc(pimpl_->document);
+    pimpl_->document = 0;
+  }
+}
+
+} //namespace xmlpp
diff --git a/libxml++/xsdschema.h b/libxml++/xsdschema.h
new file mode 100644
index 0000000..c2facf5
--- /dev/null
+++ b/libxml++/xsdschema.h
@@ -0,0 +1,104 @@
+/* Copyright (C) 2014 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_XSDSCHEMA_H
+#define __LIBXMLPP_XSDSCHEMA_H
+
+#include <libxml++/schemabase.h>
+#include <libxml++/document.h>
+#include <memory> // std::auto_ptr
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+extern "C" {
+  struct _xmlSchema;
+  struct _xmlSchemaParserCtxt;
+}
+#endif //DOXYGEN_SHOULD_SKIP_THIS
+
+namespace xmlpp
+{
+
+/** Represents an XSD schema for validating XML files.
+ * XSD = XML %Schema Definition, a.k.a. XML %Schema or W3C XML %Schema
+ *
+ * @newin{2,38}
+ */
+class XsdSchema : public SchemaBase
+{
+public:
+  XsdSchema();
+
+  /** Create a schema from the underlying libxml schema element.
+   * @param schema A pointer to the libxml schema element. The XsdSchema takes
+   *               ownership of the _xmlSchema. The caller must not deallocate it.
+   */
+  explicit XsdSchema(_xmlSchema* schema);
+
+  /** Create a schema from a schema definition file.
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  explicit XsdSchema(const Glib::ustring& filename);
+
+  /** Create a schema from an XML document.
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  explicit XsdSchema(const Document* document);
+
+  virtual ~XsdSchema();
+
+  /** Parse a schema definition file.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param filename The URL of the schema.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_file(const Glib::ustring& filename);
+
+  /** Parse a schema definition from a string.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param contents The schema definition as a string.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_memory(const Glib::ustring& contents);
+
+  /** Parse a schema definition from a document.
+   * If another schema has been parsed before, that schema is replaced by the new one.
+   * @param document A preparsed document tree, containing the schema definition.
+   * @throws xmlpp::parse_error
+   */
+  virtual void parse_document(const Document* document);
+
+  /** Access the underlying libxml implementation. */
+  _xmlSchema* cobj();
+
+  /** Access the underlying libxml implementation. */
+  const _xmlSchema* cobj() const;
+
+protected:
+  void release_underlying();
+  void parse_context(_xmlSchemaParserCtxt* context);
+
+private:
+  struct Impl;
+  std::auto_ptr<Impl> pimpl_;
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_XSDSCHEMA_H
diff --git a/libxml++config.h.in b/libxml++config.h.in
index 0bdc32e..fa36073 100755
--- a/libxml++config.h.in
+++ b/libxml++config.h.in
@@ -3,6 +3,9 @@
 
 #include <glibmmconfig.h>
 
+/* Define to omit deprecated API from the library. */
+#undef LIBXMLXX_DISABLE_DEPRECATED
+
 /* This is always set. This is only for backwards compatibility. */
 #undef LIBXMLCPP_EXCEPTIONS_ENABLED
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]