Correct eol-style property.
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
index 76fdc50..d1192dc 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2008 Internet2
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -16,7 +16,7 @@
 
 /**
  * @file xmltooling/base.h
- * 
+ *
  * Base header file definitions
  * Must be included prior to including any other header
  */
 #ifndef __xmltooling_base_h__
 #define __xmltooling_base_h__
 
+#include <typeinfo>
+
+/* Required for sprintf, used by integer XML attribute macros. */
+#include <cstdio>
+
 #if defined (_MSC_VER) || defined(__BORLANDC__)
   #include <xmltooling/config_pub_win32.h>
 #else
 # define XMLTOOLING_NO_XMLSEC 1
 #endif
 
+#if defined(XMLTOOLING_NO_XMLSEC) || !defined(HAVE_XSECSIZE_T)
+# ifdef XMLTOOLING_XERCESC_64BITSAFE
+#   include <xercesc/util/XercesDefs.hpp>
+    typedef XMLSize_t xsecsize_t;
+# else
+    typedef unsigned int xsecsize_t;
+# endif
+#endif
+
 // Windows and GCC4 Symbol Visibility Macros
 #ifdef WIN32
   #define XMLTOOL_IMPORT __declspec(dllimport)
  * Begins the declaration of an XMLObject specialization for an abstract element/type.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the base class to derive from using public virtual inheritance
  * Begins the declaration of an XMLObject specialization.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the base class to derive from using public virtual inheritance
  * Begins the declaration of an XMLObject specialization with two base classes.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the first base class to derive from using public virtual inheritance
  * Begins the declaration of an XMLObject specialization with three base classes.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the first base class to derive from using public virtual inheritance
  * Begins the declaration of an XMLObject specialization with four base classes.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the first base class to derive from using public virtual inheritance
  * Begins the declaration of an XMLObject specialization with five base classes.
  * Basic boilerplate includes a protected constructor, empty virtual destructor,
  * and Unicode constants for the default associated element's name and prefix.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the class to declare
  * @param base      the first base class to derive from using public virtual inheritance
 
 /**
  * Implements a static variable holding an XMLObject's element QName.
- * 
+ *
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
  * @param namespacePrefix   the XML namespace prefix of the default associated element
 
 /**
  * Implements a static variable holding an XMLObject's schema type QName.
- * 
+ *
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
  * @param namespacePrefix   the XML namespace prefix of the default associated element
 /**
  * Declares abstract set method for a typed XML attribute.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  * @param type      the attribute's data type
 
 /**
  * Declares abstract get/set methods for a typed XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  * @param type      the attribute's data type
 /**
  * Declares abstract set method for a string XML attribute.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 
 /**
  * Declares abstract get/set methods for a string XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 /**
  * Declares abstract set method for a DateTime XML attribute.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 
 /**
  * Declares abstract get/set methods for a DateTime XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 /**
  * Declares abstract set method for an integer XML attribute.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 
 /**
  * Declares abstract get/set methods for an integer XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  */
 
 /**
  * Declares abstract get/set methods for a boolean XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param upcased   the upcased name of the attribute
  * @param def       the default/presumed value, if no explicit value has been set
 
 /**
  * Implements get/set methods and a private member for a typed XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param type      the attribute's data type
  */
 
 /**
  * Implements get/set methods and a private member for a string XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  */
 #define IMPL_STRING_ATTRIB(proper) \
 /**
  * Implements get/set methods and a private member for a string XML attribute,
  * plus a getXMLID override.
- * 
+ *
  * @param proper    the proper name of the attribute
  */
 #define IMPL_ID_ATTRIB(proper) \
     }
 
 /**
+ * Implements get/set methods and a private member for a string XML attribute,
+ * plus a getXMLID override and attribute node clearance when DOM is dropped.
+ *
+ * @param proper    the proper name of the attribute
+ * @param ucase         the upcased name of the attribute
+ * @param namespaceURI  the XML namespace of the attribute
+ */
+#define IMPL_ID_ATTRIB_EX(proper, ucase, namespaceURI) \
+    IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
+    const XMLCh* getXMLID() const { \
+        return m_##proper; \
+    } \
+    void releaseDOM() const { \
+        if (getDOM()) \
+            getDOM()->removeAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
+        AbstractDOMCachingXMLObject::releaseDOM(); \
+    }
+
+/**
  * Implements get/set methods and a private member for a DateTime XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  * @param fallback  epoch to return when attribute is NULL
  */
 #define IMPL_DATETIME_ATTRIB(proper,fallback) \
+    IMPL_DATETIME_ATTRIB_EX(proper,fallback,false)
+
+/**
+ * Implements get/set methods and a private member for a duration-valued DateTime XML attribute.
+ *
+ * @param proper    the proper name of the attribute
+ * @param fallback  epoch to return when attribute is NULL
+ */
+#define IMPL_DURATION_ATTRIB(proper,fallback) \
+    IMPL_DATETIME_ATTRIB_EX(proper,fallback,true)
+
+/**
+ * Implements get/set methods and a private member for a DateTime XML attribute.
+ *
+ * @param proper    the proper name of the attribute
+ * @param fallback  epoch to return when attribute is NULL
+ * @param duration  true iff the attribute should be handled as a duration
+ */
+#define IMPL_DATETIME_ATTRIB_EX(proper,fallback,duration) \
     protected: \
         DateTime* m_##proper; \
         time_t m_##proper##Epoch; \
         void set##proper(const DateTime* proper) { \
             m_##proper = prepareForAssignment(m_##proper,proper); \
             if (m_##proper) \
-                m_##proper##Epoch=m_##proper->getEpoch(); \
+                m_##proper##Epoch=m_##proper->getEpoch(duration); \
         } \
         void set##proper(time_t proper) { \
-            m_##proper = prepareForAssignment(m_##proper,proper); \
+            m_##proper = prepareForAssignment(m_##proper,proper,duration); \
             m_##proper##Epoch = proper; \
         } \
         void set##proper(const XMLCh* proper) { \
-            m_##proper = prepareForAssignment(m_##proper,proper); \
+            m_##proper = prepareForAssignment(m_##proper,proper,duration); \
             if (m_##proper) \
-                m_##proper##Epoch=m_##proper->getEpoch(); \
+                m_##proper##Epoch=m_##proper->getEpoch(duration); \
         }
 
 /**
  * Implements get/set methods and a private member for an integer XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  */
 #define IMPL_INTEGER_ATTRIB(proper) \
 
 /**
  * Implements get/set methods and a private member for a boolean XML attribute.
- * 
+ *
  * @param proper    the proper name of the attribute
  */
 #define IMPL_BOOLEAN_ATTRIB(proper) \
         }
 
 /**
+ * Implements get/set methods and a private member for a typed, qualified XML attribute.
+ *
+ * @param proper    the proper name of the attribute
+ * @param type      the attribute's data type
+ */
+#define IMPL_XMLOBJECT_FOREIGN_ATTRIB(proper,type) \
+    protected: \
+    XMLCh* m_##proper##Prefix; \
+        type* m_##proper; \
+    public: \
+        const type* get##proper() const { \
+            return m_##proper; \
+        } \
+        void set##proper(const type* proper) { \
+            m_##proper = prepareForAssignment(m_##proper,proper); \
+            XMLString::release(&m_##proper##Prefix); \
+            m_##proper##Prefix = NULL; \
+        }
+
+/**
  * Declares abstract set method for a typed XML child object in a foreign namespace.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the child type
  * @param ns        the C++ namespace for the type
  */
 
 /**
  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
- * 
+ *
  * @param proper    the proper name of the child type
  * @param ns        the C++ namespace for the type
  */
 /**
  * Declares abstract set method for a typed XML child object.
  * The get method is omitted.
- * 
+ *
  * @param proper    the proper name of the child type
  */
 #define DECL_INHERITED_TYPED_CHILD(proper) \
 
 /**
  * Declares abstract get/set methods for a typed XML child object.
- * 
+ *
  * @param proper    the proper name of the child type
  */
 #define DECL_TYPED_CHILD(proper) \
 
 /**
  * Declares abstract get/set methods for a generic XML child object.
- * 
+ *
  * @param proper    the proper name of the child
  */
 #define DECL_XMLOBJECT_CHILD(proper) \
 
 /**
  * Implements get/set methods and a private list iterator member for a typed XML child object.
- * 
+ *
  * @param proper    the proper name of the child type
  */
 #define IMPL_TYPED_CHILD(proper) \
 /**
  * Implements get/set methods and a private list iterator member for
  * a typed XML child object in a foreign namespace
- * 
+ *
  * @param proper    the proper name of the child type
  * @param ns        the C++ namespace for the type
  */
 
 /**
  * Implements get/set methods and a private list iterator member for a generic XML child object.
- * 
+ *
  * @param proper    the proper name of the child
  */
 #define IMPL_XMLOBJECT_CHILD(proper) \
 
 /**
  * Declares abstract get/set methods for a typed XML child collection.
- * 
+ *
  * @param proper    the proper name of the child type
  */
 #define DECL_TYPED_CHILDREN(proper) \
 
 /**
  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
- * 
+ *
  * @param proper    the proper name of the child type
  * @param ns        the C++ namespace for the type
  */
 
 /**
  * Declares abstract get/set methods for a generic XML child collection.
- * 
+ *
  * @param proper    the proper name of the child
  */
 #define DECL_XMLOBJECT_CHILDREN(proper) \
 
 /**
  * Implements get method and a private vector member for a typed XML child collection.
- * 
+ *
  * @param proper    the proper name of the child type
  * @param fence     insertion fence for new objects of the child collection in backing list
  */
         } \
         const std::vector<proper*>& get##proper##s() const { \
             return m_##proper##s; \
-        } 
+        }
 
 /**
  * Implements get method and a private vector member for a typed XML child collection
  * in a foreign namespace.
- * 
+ *
  * @param proper    the proper name of the child type
  * @param ns        the C++ namespace for the type
  * @param fence     insertion fence for new objects of the child collection in backing list
         } \
         const std::vector<ns::proper*>& get##proper##s() const { \
             return m_##proper##s; \
-        } 
+        }
 
 /**
  * Implements get method and a private vector member for a generic XML child collection.
- * 
+ *
  * @param proper    the proper name of the child
  * @param fence     insertion fence for new objects of the child collection in backing list
  */
         } \
         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
             return m_##proper##s; \
-        } 
+        }
 
 /**
  * Implements marshalling for a string attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements marshalling for a DateTime attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements marshalling for an integer attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements marshalling for a boolean attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements marshalling for a QName attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
     }
 
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+/**
+ * Implements marshalling for an ID attribute
+ *
+ * @param proper        the proper name of the attribute
+ * @param ucase         the upcased name of the attribute
+ * @param namespaceURI  the XML namespace of the attribute
+ */
+# define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
+    if (m_##proper && *m_##proper) { \
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
+        domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, true); \
+    }
+#else
 /**
  * Implements marshalling for an ID attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
  */
-#define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
+# define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
     if (m_##proper && *m_##proper) { \
         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
     }
+#endif
 
 /**
  * Implements unmarshalling process branch for a string attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
         return; \
     }
 
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+/**
+ * Implements unmarshalling process branch for an ID attribute
+ *
+ * @param proper        the proper name of the attribute
+ * @param ucase         the upcased name of the attribute
+ * @param namespaceURI  the XML namespace of the attribute
+ */
+# define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
+    if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
+        set##proper(attribute->getValue()); \
+        attribute->getOwnerElement()->setIdAttributeNode(attribute, true); \
+        return; \
+    }
+#else
 /**
  * Implements unmarshalling process branch for an ID attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
  */
-#define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
+# define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
         set##proper(attribute->getValue()); \
         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
         return; \
     }
+#endif
 
 /**
  * Implements unmarshalling process branch for a DateTime attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements unmarshalling process branch for a DateTime attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements unmarshalling process branch for an integer attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements unmarshalling process branch for a boolean attribute
- * 
+ *
  * @param proper        the proper name of the attribute
  * @param ucase         the upcased name of the attribute
  * @param namespaceURI  the XML namespace of the attribute
 
 /**
  * Implements unmarshalling process branch for typed child collection element
- * 
+ *
  * @param proper        the proper name of the child type
  * @param namespaceURI  the XML namespace of the child element
  * @param force         bypass use of hint and just cast down to check child
 /**
  * Implements unmarshalling process branch for typed child collection element
  * in a foreign namespace.
- * 
+ *
  * @param proper        the proper name of the child type
  * @param ns            the C++ namespace for the type
  * @param namespaceURI  the XML namespace of the child element
 
 /**
  * Implements unmarshalling process branch for typed child singleton element
- * 
+ *
  * @param proper        the proper name of the child type
  * @param namespaceURI  the XML namespace of the child element
  * @param force         bypass use of hint and just cast down to check child
 /**
  * Implements unmarshalling process branch for typed child singleton element
  * in a foreign namespace.
- * 
+ *
  * @param proper        the proper name of the child type
  * @param ns            the C++ namespace for the type
  * @param namespaceURI  the XML namespace of the child element
 
 /**
  * Implements unmarshalling process branch for a generic child singleton element
- * 
+ *
  * @param proper        the proper name of the child type
  * @param namespaceURI  the XML namespace of the child element
  */
 
 /**
  * Declares aliased get/set methods for named XML element simple content.
- * 
+ *
  * @param proper    the proper name to label the element's content
  */
 #define DECL_SIMPLE_CONTENT(proper) \
 
 /**
  * Declares aliased get/set methods for named integer XML element content.
- * 
+ *
  * @param proper    the proper name to label the element's content
  */
 #define DECL_INTEGER_CONTENT(proper) \
 
 /**
  * Implements cloning methods for an XMLObject specialization implementation class.
- * 
+ *
  * @param cname    the name of the XMLObject specialization
  */
 #define IMPL_XMLOBJECT_CLONE(cname) \
 /**
  * Declares an XMLObject specialization with a simple content model and type,
  * handling it as string data.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the XMLObject specialization
  * @param proper    the proper name to label the element's content
 /**
  * Declares and defines an implementation class for an XMLObject with
  * a simple content model and type, handling it as string data.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the XMLObject specialization
  */
     { \
     public: \
         virtual ~cname##Impl() {} \
-        cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) \
+        cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \
             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
         } \
         cname##Impl(const cname##Impl& src) \
  * Begins the declaration of an XMLObjectBuilder specialization.
  * Basic boilerplate includes an empty virtual destructor, and
  * a default builder that defaults the element name.
- * 
+ *
  * @param linkage           linkage specifier for the class
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
  */
 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
-    class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
+    class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
     public: \
         virtual ~cname##Builder() {} \
         XMLTOOLING_DOXYGEN(Default builder.) \
 
 /**
  * Declares a generic XMLObjectBuilder specialization.
- * 
+ *
  * @param linkage           linkage specifier for the class
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
     END_XMLOBJECTBUILDER
 
 /**
- * Implements the standard XMLObjectBuilder specialization function. 
- * 
+ * Implements the standard XMLObjectBuilder specialization function.
+ *
  * @param cname the name of the XMLObject specialization
  */
 #define IMPL_XMLOBJECTBUILDER(cname) \
     cname* cname##Builder::buildObject( \
-        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
+        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
         ) const \
     { \
         return new cname##Impl(nsURI,localName,prefix,schemaType); \
  * Begins the declaration of an XMLObjectBuilder specialization.
  * Basic boilerplate includes an empty virtual destructor, and
  * a default builder that defaults the element name.
- * 
+ *
  * @param linkage           linkage specifier for the class
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
  */
 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
-    class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
+    class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
     public: \
         virtual ~cname##Builder() {} \
         XMLTOOLING_DOXYGEN(Default builder.) \
 
 /**
  * Declares a generic XMLObjectBuilder specialization.
- * 
+ *
  * @param linkage           linkage specifier for the class
  * @param cname             the name of the XMLObject specialization
  * @param namespaceURI      the XML namespace of the default associated element
     END_XMLOBJECTBUILDER
 
 /**
- * Implements the standard XMLObjectBuilder specialization function. 
- * 
+ * Implements the standard XMLObjectBuilder specialization function.
+ *
  * @param cname the name of the XMLObject specialization
  */
 #define IMPL_XMLOBJECTBUILDER(cname) \
     xmltooling::XMLObject* cname##Builder::buildObject( \
-        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
+        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
         ) const \
     { \
         return new cname##Impl(nsURI,localName,prefix,schemaType); \
 
 /**
  * Begins the declaration of a Schema Validator specialization.
- * 
+ *
  * @param linkage           linkage specifier for the class
  * @param cname the base name of the Validator specialization
  */
         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
             if (!ptr) \
-                throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
+                throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())); \
+            if (ptr->nil() && (ptr->hasChildren() || ptr->getTextContent())) \
+               throw xmltooling::ValidationException("Object has nil property but with children or content.")
 
 /**
  * Begins the declaration of a Schema Validator specialization subclass.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the base name of the Validator specialization
  * @param base      base class for the validator
         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
             if (!ptr) \
-                throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
+                throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()));
 
 /**
  * Ends the declaration of a Validator specialization.
 
 /**
  * Validator code that checks the object type.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
  */
 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
 
 /**
  * Validator code that checks for a required attribute, content, or singleton.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper    the proper name of the attribute, content, or singleton member 
+ * @param proper    the proper name of the attribute, content, or singleton member
  */
 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
     if (!ptr->get##proper()) \
 
 /**
  * Validator code that checks for a required integer attribute
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper    the proper name of the attribute, content, or singleton member 
+ * @param proper    the proper name of the attribute, content, or singleton member
  */
 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
     if (!ptr->get##proper().first) \
 /**
  * Validator code that checks for one of a pair of
  * required attributes, content, or singletons.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper1   the proper name of the first attribute, content, or singleton member 
- * @param proper2   the proper name of the second attribute, content, or singleton member 
+ * @param proper1   the proper name of the first attribute, content, or singleton member
+ * @param proper2   the proper name of the second attribute, content, or singleton member
  */
 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
     if (!ptr->get##proper1() && !ptr->get##proper2()) \
 /**
  * Validator code that checks for one of a pair of
  * required attributes, content, or singletons, but disallows both.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper1   the proper name of the first attribute, content, or singleton member 
- * @param proper2   the proper name of the second attribute, content, or singleton member 
+ * @param proper1   the proper name of the first attribute, content, or singleton member
+ * @param proper2   the proper name of the second attribute, content, or singleton member
  */
 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
 /**
  * Validator code that checks for one of a set of three
  * required attributes, content, or singletons.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
  * @param proper1   the proper name of the first attribute, content, or singleton member
  * @param proper2   the proper name of the second attribute, content, or singleton member
 /**
  * Validator code that checks for one of a set of three
  * required attributes, content, or singletons but disallows more than one.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
  * @param proper1   the proper name of the first attribute, content, or singleton member
  * @param proper2   the proper name of the second attribute, content, or singleton member
 /**
  * Validator code that checks a co-constraint (if one present, the other must be)
  * between a pair of attributes, content, or singletons.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper1   the proper name of the first attribute, content, or singleton member 
- * @param proper2   the proper name of the second attribute, content, or singleton member 
+ * @param proper1   the proper name of the first attribute, content, or singleton member
+ * @param proper2   the proper name of the second attribute, content, or singleton member
  */
 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
 
 /**
  * Validator code that checks for a non-empty collection.
- * 
+ *
  * @param cname     the name of the XMLObject specialization
- * @param proper    the proper name of the collection item 
+ * @param proper    the proper name of the collection item
  */
 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
     if (ptr->get##proper##s().empty()) \
 /**
  * Declares/defines a Validator specialization that checks object type and
  * a non-empty simple content model.
- * 
+ *
  * @param linkage   linkage specifier for the class
  * @param cname     the name of the XMLObject specialization
  */
@@ -1511,7 +1616,7 @@ namespace xmltooling {
      * Template function for cloning a sequence of XMLObjects.
      * Invokes the clone() member on each element of the input sequence and adds the copy to
      * the output sequence. Order is preserved.
-     * 
+     *
      * @param in    input sequence to clone
      * @param out   output sequence to copy cloned pointers into
      */
@@ -1531,14 +1636,14 @@ namespace xmltooling {
     {
         /**
          * Function operator to delete an object.
-         * 
+         *
          * @param ptr   object to delete
          */
         void operator()(T* ptr) {delete ptr;}
-        
+
         /**
          * Function operator to delete an object stored as const.
-         * 
+         *
          * @param ptr   object to delete after casting away const
          */
         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
@@ -1551,7 +1656,7 @@ namespace xmltooling {
     {
         /**
          * Function operator to delete an object.
-         * 
+         *
          * @param p   a pair in which the second component is the object to delete
          */
         void operator()(const std::pair<const A,B*>& p) {delete p.second;}
@@ -1564,7 +1669,7 @@ namespace xmltooling {
     {
         /**
          * Function operator to delete an object stored as const
-         * 
+         *
          * @param p   a pair in which the second component is the const object to delete
          */
         void operator()(const std::pair<const A,const B*>& p) {delete const_cast<B*>(p.second);}