summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--doc/cxx/tree/manual/index.xhtml94
-rw-r--r--libxsd/xsd/cxx/tree/comparison-map.txx19
-rw-r--r--libxsd/xsd/cxx/tree/containers-wildcard.hxx2
-rw-r--r--libxsd/xsd/cxx/tree/containers.hxx256
-rw-r--r--libxsd/xsd/cxx/tree/elements.hxx386
-rw-r--r--libxsd/xsd/cxx/tree/elements.ixx213
-rw-r--r--libxsd/xsd/cxx/tree/elements.txx8
-rw-r--r--libxsd/xsd/cxx/tree/iterator-adapter.hxx270
-rw-r--r--libxsd/xsd/cxx/tree/list.hxx2
-rw-r--r--libxsd/xsd/cxx/tree/parsing.txx62
-rw-r--r--libxsd/xsd/cxx/tree/serialization.txx41
-rw-r--r--libxsd/xsd/cxx/tree/std-ostream-map.txx2
-rw-r--r--libxsd/xsd/cxx/tree/std-ostream-operators.hxx6
-rw-r--r--libxsd/xsd/cxx/tree/stream-extraction-map.txx2
-rw-r--r--libxsd/xsd/cxx/tree/stream-extraction.hxx16
-rw-r--r--libxsd/xsd/cxx/tree/stream-insertion-map.txx2
-rw-r--r--libxsd/xsd/cxx/tree/stream-insertion.hxx8
-rw-r--r--libxsd/xsd/cxx/tree/type-factory-map.txx2
-rw-r--r--libxsd/xsd/cxx/tree/type-serializer-map.txx2
-rw-r--r--libxsd/xsd/cxx/tree/types.hxx166
-rw-r--r--libxsd/xsd/cxx/xml/string.hxx17
-rw-r--r--tests/cxx/tree/any-type/driver.cxx145
-rw-r--r--tests/cxx/tree/any-type/makefile87
-rw-r--r--tests/cxx/tree/any-type/output73
-rw-r--r--tests/cxx/tree/any-type/test.xml26
-rw-r--r--tests/cxx/tree/any-type/test.xsd19
-rw-r--r--tests/cxx/tree/binary/cdr/driver.cxx8
-rw-r--r--tests/cxx/tree/binary/cdr/makefile2
-rw-r--r--tests/cxx/tree/binary/cdr/test.xml4
-rw-r--r--tests/cxx/tree/binary/cdr/test.xsd3
-rw-r--r--tests/cxx/tree/binary/polymorphic/makefile3
-rw-r--r--tests/cxx/tree/binary/xdr/driver.cxx8
-rw-r--r--tests/cxx/tree/binary/xdr/makefile3
-rw-r--r--tests/cxx/tree/binary/xdr/test.xml4
-rw-r--r--tests/cxx/tree/binary/xdr/test.xsd3
-rw-r--r--tests/cxx/tree/compilation/driver.cxx2
-rw-r--r--tests/cxx/tree/makefile1
-rw-r--r--xsd/cxx/tree/fundamental-header.hxx2
-rw-r--r--xsd/cxx/tree/options.cli7
-rw-r--r--xsd/cxx/tree/stream-extraction-source.cxx22
-rw-r--r--xsd/cxx/tree/tree-header.cxx16
-rw-r--r--xsd/cxx/tree/tree-inline.cxx22
-rw-r--r--xsd/cxx/tree/tree-source.cxx8
44 files changed, 1663 insertions, 389 deletions
diff --git a/NEWS b/NEWS
index bb220b9..0145a07 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,14 @@ C++/Tree
to Section 2.13, "Mapping for Mixed Content Models" in the C++/Tree
Mapping User Manual.
+ * xml_schema::typecan represent anyType content as a DOM fragment, similar
+ to wildcards. For more information, refer to Section 2.5.2, "Mapping for
+ anyType" in the C++/Tree Mapping User Manual.
+
+ * xml_schema::simple_type can represent anySimpleType content as a text
+ string. For more information, refer to Section 2.5.3, "Mapping for
+ anySimpleType" in the C++/Tree Mapping User Manual.
+
* New option, --suppress-assignment, suppress the generation of copy
assignment operators for complex types. If this option is specified,
the copy assignment operators for such types are declared private
diff --git a/doc/cxx/tree/manual/index.xhtml b/doc/cxx/tree/manual/index.xhtml
index 052f2b3..235c33c 100644
--- a/doc/cxx/tree/manual/index.xhtml
+++ b/doc/cxx/tree/manual/index.xhtml
@@ -1214,18 +1214,44 @@ public:
virtual
~type ();
-public:
type ();
type (const type&);
-public:
type&
operator= (const type&);
-public:
virtual type*
_clone () const;
+ // anyType DOM content.
+ //
+public:
+ typedef element_optional dom_content_optional;
+
+ const dom_content_optional&
+ dom_content () const;
+
+ dom_content_optional&
+ dom_content ();
+
+ void
+ dom_content (const xercesc::DOMElement&);
+
+ void
+ dom_content (xercesc::DOMElement*);
+
+ void
+ dom_content (const dom_content_optional&);
+
+ const xercesc::DOMDocument&
+ dom_content_document () const;
+
+ xercesc::DOMDocument&
+ dom_content_document ();
+
+ bool
+ null_content () const;
+
// DOM association.
//
public:
@@ -1237,7 +1263,44 @@ public:
};
</pre>
- <p>For more information about DOM association refer to
+ <p>When <code>xml_schema::type</code> is used to create an instance
+ (as opposed to being a base of a derived type), it represents
+ the XML Schema <code>anyType</code> type. <code>anyType</code>
+ allows any attributes and any content in any order. In the
+ C++/Tree mapping this content can be represented as a DOM
+ fragment, similar to XML Schema wildcards (<a href="#2.12">Section
+ 2.12, "Mapping for <code>any</code> and
+ <code>anyAttribute</code>"</a>).</p>
+
+ <p>To enable automatic extraction of <code>anyType</code> content
+ during parsing, the <code>--generate-any-type</code> option must be
+ specified. Because the DOM API is used to access such content, the
+ Xerces-C++ runtime should be initialized by the application prior to
+ parsing and should remain initialized for the lifetime of objects
+ with the DOM content. For more information on the Xerces-C++ runtime
+ initialization see <a href="#3.1">Section 3.1, "Initializing the
+ Xerces-C++ Runtime"</a>.</p>
+
+ <p>The DOM content is stored as the optional DOM element container
+ and the DOM content accessors and modifiers presented above are
+ identical to those generated for an optional element wildcard.
+ Refer to <a href="#2.12.2">Section 2.12.2, "Mapping for <code>any</code>
+ with the Optional Cardinality Class"</a> for details on their
+ semantics.</p>
+
+ <p>The <code>dom_content_document()</code> function returns the
+ DOM document used to store the raw XML content corresponding
+ to the <code>anyType</code> instance. It is equivalent to the
+ <code>dom_document()</code> function generated for types
+ with wildcards.</p>
+
+ <p>The <code>null_content()</code> accessor is an optimization function
+ that allows us to check for the lack of content without actually
+ creating its empty representation, that is, empty DOM document for
+ <code>anyType</code> or empty string for <code>anySimpleType</code>
+ (see the following section for details on <code>anySimpleType</code>).</p>
+
+ <p>For more information on DOM association refer to
<a href="#5.1">Section 5.1, "DOM Association"</a>.</p>
<h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3>
@@ -1250,18 +1313,37 @@ class simple_type: public type
{
public:
simple_type ();
+ simple_type (const C*);
+ simple_type (const std::basic_string&lt;C>&amp;);
+
simple_type (const simple_type&amp;);
-public:
simple_type&amp;
operator= (const simple_type&amp;);
-public:
virtual simple_type*
_clone () const;
+
+ // anySimpleType text content.
+ //
+public:
+ const std::basic_string&lt;C>&amp;
+ text_content () const;
+
+ std::basic_string&lt;C>&amp;
+ text_content ();
+
+ void
+ text_content (const std::basic_string&lt;C>&amp;);
};
</pre>
+ <p>When <code>xml_schema::simple_type</code> is used to create an instance
+ (as opposed to being a base of a derived type), it represents
+ the XML Schema <code>anySimpleType</code> type. <code>anySimpleType</code>
+ allows any simple content. In the C++/Tree mapping this content can
+ be represented as a string and accessed or modified with the
+ <code>text_content()</code> functions shown above.</p>
<h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3>
diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx
index e996aec..af23d64 100644
--- a/libxsd/xsd/cxx/tree/comparison-map.txx
+++ b/libxsd/xsd/cxx/tree/comparison-map.txx
@@ -19,18 +19,17 @@ namespace xsd
// anyType and anySimpleType.
//
- //register_type (
- // typeid (type),
- // &comparator_impl<type>,
- // false);
-
- typedef simple_type<type> simple_type;
+ register_type (
+ typeid (type),
+ &comparator_impl<type>,
+ false);
- //register_type (
- // typeid (simple_type),
- // &comparator_impl<simple_type>,
- // false);
+ typedef simple_type<C, type> simple_type;
+ register_type (
+ typeid (simple_type),
+ &comparator_impl<simple_type>,
+ false);
// Strings
//
diff --git a/libxsd/xsd/cxx/tree/containers-wildcard.hxx b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
index f4d3be2..549df73 100644
--- a/libxsd/xsd/cxx/tree/containers-wildcard.hxx
+++ b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
@@ -15,7 +15,7 @@
#include <xsd/cxx/xml/string.hxx>
-#include <xsd/cxx/tree/containers.hxx> // iterator_adapter
+#include <xsd/cxx/tree/iterator-adapter.hxx>
namespace xsd
{
diff --git a/libxsd/xsd/cxx/tree/containers.hxx b/libxsd/xsd/cxx/tree/containers.hxx
index c89218f..cafd79d 100644
--- a/libxsd/xsd/cxx/tree/containers.hxx
+++ b/libxsd/xsd/cxx/tree/containers.hxx
@@ -5,17 +5,15 @@
#ifndef XSD_CXX_TREE_CONTAINERS_HXX
#define XSD_CXX_TREE_CONTAINERS_HXX
-#include <cstddef> // std::ptrdiff_t
-#include <string>
#include <vector>
#include <memory> // std::auto_ptr/unique_ptr
-#include <iterator> // std::iterator_traits
#include <algorithm> // std::equal, std::lexicographical_compare
#include <iosfwd>
#include <xsd/cxx/config.hxx> // XSD_AUTO_PTR
#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/iterator-adapter.hxx>
namespace xsd
{
@@ -515,7 +513,7 @@ namespace xsd
return !(a < b);
}
- // Provide an ostream insertion opretaor to prevent confusion from
+ // Provide an ostream insertion operator to prevent confusion from
// the implicit bool conversion.
//
template <typename C, typename T, bool fund>
@@ -528,256 +526,6 @@ namespace xsd
template <typename T, bool fund = fundamental_p<T>::r>
class sequence;
- // Sun CC's <iterator> does not have iterator_traits. To overcome
- // this, we will wrap std::iterator_traits into our own and also
- // specialize it for pointer types. Since Sun CC uses pointer
- // for vector::iterator, it will use the specialization and won't
- // notice the std::iterator_traits.
- //
-#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
- template <typename I>
- struct iterator_traits
- {
- typedef
- typename std::iterator_traits<I>::iterator_category
- iterator_category;
-
- typedef
- typename std::iterator_traits<I>::value_type
- value_type;
-
- typedef
- typename std::iterator_traits<I>::difference_type
- difference_type;
- };
-#else
- // The Pointer specialization does not work for reverse and
- // set iterators. But these iterators are user-dfined types
- // and have suitable typedefs that we can use.
- //
- template <typename I>
- struct iterator_traits
- {
- typedef typename I::iterator_category iterator_category;
- typedef typename I::value_type value_type;
- typedef typename I::difference_type difference_type;
- };
-
- template <typename T>
- struct iterator_traits<T*>
- {
- typedef std::random_access_iterator_tag iterator_category;
- typedef T value_type;
- typedef std::ptrdiff_t difference_type;
- };
-#endif
-
- // Iterator adapter for complex types. It expects I to point to
- // a smart pointer-like object that has operator*() that returns
- // a refernce to a type static_cast'able to T and get() that
- // returns a pointer to a type static_cast'able to T.
- //
-
- template <typename I, typename T>
- struct iterator_adapter
- {
- typedef T value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
-
- typedef
- typename iterator_traits<I>::iterator_category
- iterator_category;
-
- typedef
- typename iterator_traits<I>::difference_type
- difference_type;
-
-
- public:
- iterator_adapter ()
- : i_ () // i_ can be of a pointer type.
- {
- }
-
- // Allow iterator to const_iterator conversion.
- //
- template <typename J, typename T2>
- iterator_adapter (const iterator_adapter<J, T2>& j)
- : i_ (j.base ())
- {
- }
-
- explicit
- iterator_adapter (const I& i)
- : i_ (i)
- {
- }
-
- public:
- // Forward iterator requirements.
- //
- reference
- operator* () const
- {
- return static_cast<reference> (**i_);
- }
-
- pointer
- operator-> () const
- {
- return static_cast<pointer> (i_->get ());
- }
-
- iterator_adapter&
- operator++ ()
- {
- ++i_;
- return *this;
- }
-
- iterator_adapter
- operator++ (int)
- {
- iterator_adapter r (*this);
- ++i_;
- return r;
- }
-
- // Bidirectional iterator requirements.
- //
- iterator_adapter&
- operator-- ()
- {
- --i_;
- return *this;
- }
-
- iterator_adapter
- operator-- (int)
- {
- iterator_adapter r (*this);
- --i_;
- return r;
- }
-
- // Random access iterator requirements.
- //
- reference
- operator[] (difference_type n) const
- {
- return static_cast<reference> (*(i_[n]));
- }
-
- iterator_adapter&
- operator+= (difference_type n)
- {
- i_ += n;
- return *this;
- }
-
- iterator_adapter
- operator+ (difference_type n) const
- {
- return iterator_adapter (i_ + n);
- }
-
- iterator_adapter&
- operator-= (difference_type n)
- {
- i_ -= n;
- return *this;
- }
-
- iterator_adapter
- operator- (difference_type n) const
- {
- return iterator_adapter (i_ - n);
- }
-
- public:
- const I&
- base () const
- {
- return i_;
- }
-
- private:
- I i_;
- };
-
- // Note: We use different types for left- and right-hand-side
- // arguments to allow comparison between iterator and const_iterator.
- //
-
- // Forward iterator requirements.
- //
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator== (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () == j.base ();
- }
-
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator!= (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () != j.base ();
- }
-
- // Random access iterator requirements
- //
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator< (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () < j.base ();
- }
-
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator> (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () > j.base ();
- }
-
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator<= (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () <= j.base ();
- }
-
- template <typename I, typename J, typename T1, typename T2>
- inline bool
- operator>= (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () >= j.base ();
- }
-
- template <typename I, typename J, typename T1, typename T2>
- inline typename iterator_adapter<I, T1>::difference_type
- operator- (const iterator_adapter<I, T1>& i,
- const iterator_adapter<J, T2>& j)
- {
- return i.base () - j.base ();
- }
-
- template <typename I, typename T>
- inline iterator_adapter<I, T>
- operator+ (typename iterator_adapter<I, T>::difference_type n,
- const iterator_adapter<I, T>& i)
- {
- return iterator_adapter<I, T> (i.base () + n);
- }
-
//
//
class sequence_common
diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx
index 89be61e..ee32a62 100644
--- a/libxsd/xsd/cxx/tree/elements.hxx
+++ b/libxsd/xsd/cxx/tree/elements.hxx
@@ -40,10 +40,12 @@
#include <xsd/cxx/xml/elements.hxx> // xml::properties
#include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr/unique_ptr
+#include <xsd/cxx/xml/dom/wildcard-source.hxx> // dom::create_document()
#include <xsd/cxx/tree/facet.hxx>
#include <xsd/cxx/tree/exceptions.hxx>
#include <xsd/cxx/tree/istream-fwd.hxx>
+#include <xsd/cxx/tree/containers-wildcard.hxx>
#if _XERCES_VERSION < 30000
# error Xerces-C++ 2-series is not supported
@@ -101,6 +103,12 @@ namespace xsd
static const unsigned long dont_validate = 0x00000400UL;
/**
+ * @brief Extract XML content for anyType or anySimpleType.
+ * Normally you don't need to specify this flag explicitly.
+ */
+ static const unsigned long extract_content = 0x00000800UL;
+
+ /**
* @brief Do not initialize the Xerces-C++ runtime.
*/
static const unsigned long dont_initialize = 0x00000001UL;
@@ -330,9 +338,14 @@ namespace xsd
_type ();
/**
- * @brief Create an instance from a string.
+ * @brief Create an instance from a C string.
*
* @param s A string to initialize the instance with.
+ *
+ * Note that this constructor ignores the string and creates an
+ * empty anyType instance. In particular, it will not convert the
+ * string into DOM content. The purpose of such a strange constructor
+ * is to allow statically-initialized default values of anyType type.
*/
template <typename C>
_type (const C* s);
@@ -387,7 +400,9 @@ namespace xsd
* @param c A pointer to the object that will contain the new
* instance.
*/
- _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+ _type (const xercesc::DOMElement& e,
+ flags f = flags::extract_content,
+ container* c = 0);
/**
* @brief Create an instance from a DOM Attribute.
@@ -427,6 +442,11 @@ namespace xsd
{
if (this != &x)
{
+ if (x.content_.get () == 0)
+ content_.reset ();
+ else
+ content_ = x.content_->clone ();
+
// Drop DOM association.
//
dom_info_.reset ();
@@ -435,6 +455,135 @@ namespace xsd
return *this;
}
+ // anyType content API.
+ //
+ public:
+ typedef element_optional dom_content_optional;
+
+ /**
+ * @brief Return a read-only (constant) reference to the anyType
+ * DOM content.
+ *
+ * @return A constant reference to the optional container.
+ *
+ * The DOM content is returned as an optional element container,
+ * the same container as used for optional element wildcards.
+ */
+ const dom_content_optional&
+ dom_content () const;
+
+ /**
+ * @brief Return a read-write reference to the anyType DOM content.
+ *
+ * @return A reference to the optional container.
+ *
+ * The DOM content is returned as an optional element container,
+ * the same container as used for optional element wildcards.
+ */
+ dom_content_optional&
+ dom_content ();
+
+ /**
+ * @brief Set the anyType DOM content.
+ *
+ * @param e A new element to set.
+ *
+ * This function makes a copy of its argument and sets it as the
+ * new DOM content.
+ */
+ void
+ dom_content (const xercesc::DOMElement& e);
+
+ /**
+ * @brief Set the anyType DOM content.
+ *
+ * @param e A new element to use.
+ *
+ * This function will use the passed element directly instead
+ * of making a copy. For this to work the element should belong
+ * to the DOM document associated with this anyType instance.
+ *
+ * @see dom_content_document
+ */
+ void
+ dom_content (xercesc::DOMElement* e);
+
+ /**
+ * @brief Set the anyType DOM content.
+ *
+ * @param d An optional container with the new element to set.
+ *
+ * If the element is present in @a d then this function makes a
+ * copy of this element and sets it as the new wildcard content.
+ * Otherwise the element container is set the 'not present' state.
+ */
+ void
+ dom_content (const dom_content_optional& d);
+
+ /**
+ * @brief Return a read-only (constant) reference to the DOM
+ * document associated with this anyType instance.
+ *
+ * @return A constant reference to the DOM document.
+ *
+ * The DOM document returned by this function is used to store
+ * the raw XML content corresponding to the anyType instance.
+ */
+ const xercesc::DOMDocument&
+ dom_content_document () const;
+
+ /**
+ * @brief Return a read-write reference to the DOM document
+ * associated with this anyType instance.
+ *
+ * @return A reference to the DOM document.
+ *
+ * The DOM document returned by this function is used to store
+ * the raw XML content corresponding to the anyType instance.
+ */
+ xercesc::DOMDocument&
+ dom_content_document ();
+
+ /**
+ * @brief Check for absence of DOM (anyType) and text (anySimpleType)
+ * content.
+ *
+ * @return True if there is no content and false otherwise.
+ *
+ * This is an optimization function that allows us to check for the
+ * lack of content without actually creating its empty representation
+ * (that is, empty DOM document for DOM or empty string for text).
+ */
+ bool
+ null_content () const;
+
+ //
+ //
+ public:
+ /**
+ * @brief Comparison operator. It uses DOM (anyType) or text
+ * (anySimpleType) content if present. If the content is missing
+ * then the types are assumed unequal.
+ *
+ * @return True if the instances are equal, false otherwise.
+ */
+ friend bool
+ operator== (const type& x, const type& y)
+ {
+ return x.content_.get () != 0 &&
+ x.content_->compare (y.content_.get ());
+ }
+
+ /**
+ * @brief Comparison operator. It uses DOM (anyType) or text
+ * (anySimpleType) content if present. If the content is missing
+ * then the types are assumed unequal.
+ *
+ * @return True if the instances are not equal, false otherwise.
+ */
+ friend bool
+ operator!= (const type& x, const type& y) {return !(x == y);}
+
// Container API.
//
public:
@@ -738,13 +887,9 @@ namespace xsd
struct dom_info
{
virtual
- ~dom_info ()
- {
- }
+ ~dom_info () {}
- dom_info ()
- {
- }
+ dom_info () {}
virtual XSD_AUTO_PTR<dom_info>
clone (type& tree_node, container*) const = 0;
@@ -754,12 +899,9 @@ namespace xsd
private:
dom_info (const dom_info&);
-
- dom_info&
- operator= (const dom_info&);
+ dom_info& operator= (const dom_info&);
};
-
struct dom_element_info: public dom_info
{
dom_element_info (xercesc::DOMElement& e, type& n, bool root)
@@ -994,20 +1136,75 @@ namespace xsd
XSD_AUTO_PTR<map> map_;
- private:
- container* container_;
- };
+ // anyType and anySimpleType content.
+ //
+ protected:
- inline _type::
- _type (const type& x, flags f, container* c)
- : container_ (c)
- {
- if (x.dom_info_.get () != 0 && (f & flags::keep_dom))
+ //@cond
+
+ struct content_type
{
- dom_info_ = x.dom_info_->clone (*this, c);
- }
- }
+ virtual
+ ~content_type () {}
+
+ content_type () {}
+
+ virtual XSD_AUTO_PTR<content_type>
+ clone () const = 0;
+
+ virtual bool
+ compare (const content_type*) const = 0;
+
+ private:
+ content_type (const content_type&);
+ content_type& operator= (const content_type&);
+ };
+
+ struct dom_content_type: content_type
+ {
+ dom_content_type ()
+ : doc (xml::dom::create_document<char> ()), dom (*doc) {}
+ explicit
+ dom_content_type (const xercesc::DOMElement& e)
+ : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
+
+ explicit
+ dom_content_type (xercesc::DOMElement* e)
+ : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
+
+ explicit
+ dom_content_type (const dom_content_optional& d)
+ : doc (xml::dom::create_document<char> ()), dom (d, *doc) {}
+
+ virtual XSD_AUTO_PTR<content_type>
+ clone () const
+ {
+ return XSD_AUTO_PTR<content_type> (new dom_content_type (dom));
+ }
+
+ virtual bool
+ compare (const content_type* c) const
+ {
+ if (const dom_content_type* dc =
+ dynamic_cast<const dom_content_type*> (c))
+ return dom == dc->dom;
+
+ return false;
+ }
+
+ public:
+ XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc;
+ dom_content_optional dom;
+ };
+
+ //@endcond
+
+ mutable XSD_AUTO_PTR<content_type> content_;
+
+ private:
+ container* container_;
+ };
/**
* @brief Class corresponding to the XML Schema anySimpleType built-in
@@ -1015,7 +1212,7 @@ namespace xsd
*
* @nosubgrouping
*/
- template <typename B>
+ template <typename C, typename B>
class simple_type: public B
{
public:
@@ -1030,13 +1227,19 @@ namespace xsd
simple_type ();
/**
- * @brief Create an instance from a string.
+ * @brief Create an instance from a C string.
*
* @param s A string to initialize the instance with.
*/
- template <typename C>
simple_type (const C* s);
+ /**
+ * @brief Create an instance from a string.
+ *
+ * @param s A string to initialize the instance with.
+ */
+ simple_type (const std::basic_string<C>& s);
+
public:
/**
* @brief Copy constructor.
@@ -1074,7 +1277,9 @@ namespace xsd
* instance.
*/
template <typename S>
- simple_type (istream<S>& s, flags f = 0, container* c = 0);
+ simple_type (istream<S>& s,
+ flags f = flags::extract_content,
+ container* c = 0);
/**
* @brief Create an instance from a DOM element.
@@ -1085,7 +1290,7 @@ namespace xsd
* instance.
*/
simple_type (const xercesc::DOMElement& e,
- flags f = 0,
+ flags f = flags::extract_content,
container* c = 0);
/**
@@ -1097,7 +1302,7 @@ namespace xsd
* instance.
*/
simple_type (const xercesc::DOMAttr& a,
- flags f = 0,
+ flags f = flags::extract_content,
container* c = 0);
/**
@@ -1109,12 +1314,82 @@ namespace xsd
* @param c A pointer to the object that will contain the new
* instance.
*/
- template <typename C>
simple_type (const std::basic_string<C>& s,
const xercesc::DOMElement* e,
- flags f = 0,
+ flags f = flags::extract_content,
container* c = 0);
//@}
+
+ // anySimpleType content API.
+ //
+ public:
+ /**
+ * @brief Return a read-only (constant) reference to the anySimpleType
+ * text content.
+ *
+ * @return A constant reference to the text string.
+ */
+ const std::basic_string<C>&
+ text_content () const;
+
+ /**
+ * @brief Return a read-write reference to the anySimpleType text
+ * content.
+ *
+ * @return A reference to the text string.
+ */
+ std::basic_string<C>&
+ text_content ();
+
+ /**
+ * @brief Set the anySimpleType text content.
+ *
+ * @param e A new text string to set.
+ */
+ void
+ text_content (const std::basic_string<C>& t);
+
+ protected:
+ //@cond
+
+ typedef typename B::content_type content_type;
+
+ struct text_content_type: content_type
+ {
+ text_content_type () {}
+
+ explicit
+ text_content_type (const std::basic_string<C>& t): text (t) {}
+
+ explicit
+ text_content_type (const C* t): text (t) {}
+
+ virtual XSD_AUTO_PTR<content_type>
+ clone () const
+ {
+ return XSD_AUTO_PTR<content_type> (new text_content_type (text));
+ }
+
+ virtual bool
+ compare (const content_type* c) const
+ {
+ if (const text_content_type* tc =
+ dynamic_cast<const text_content_type*> (c))
+ return text == tc->text;
+
+ return false;
+ }
+
+ public:
+ // It would have been more elegant to store text content as DOMText.
+ // However, that would require Xerces-C++ initialization. Also
+ // having a separate DOMDocument for each text node seems like
+ // an overkill.
+ //
+ std::basic_string<C> text;
+ };
+
+ //@endcond
};
@@ -1233,8 +1508,57 @@ namespace xsd
{
return XSD_AUTO_PTR<T> (new T (s, e, f, c));
}
+
+ // For now for istream we only go through traits for non-
+ // fundamental types.
+ //
+ template <typename S>
+ static XSD_AUTO_PTR<T>
+ create (istream<S>& s, flags f, container* c)
+ {
+ return XSD_AUTO_PTR<T> (new T (s, f, c));
+ }
};
+ template <typename B,
+ typename C,
+ schema_type::value ST>
+ struct traits<simple_type<C, B>, C, ST>
+ {
+ typedef simple_type<C, B> type;
+
+ static XSD_AUTO_PTR<type>
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return XSD_AUTO_PTR<type> (
+ new type (e, f | flags::extract_content, c));
+ }
+
+ static XSD_AUTO_PTR<type>
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return XSD_AUTO_PTR<type> (
+ new type (a, f | flags::extract_content, c));
+ }
+
+ static XSD_AUTO_PTR<type>
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ {
+ return XSD_AUTO_PTR<type> (
+ new type (s, e, f | flags::extract_content, c));
+ }
+
+ template <typename S>
+ static XSD_AUTO_PTR<type>
+ create (istream<S>& s, flags f, container* c)
+ {
+ return XSD_AUTO_PTR<type> (
+ new type (s, f | flags::extract_content, c));
+ }
+ };
//@endcond
diff --git a/libxsd/xsd/cxx/tree/elements.ixx b/libxsd/xsd/cxx/tree/elements.ixx
index da8a83e..844ccf7 100644
--- a/libxsd/xsd/cxx/tree/elements.ixx
+++ b/libxsd/xsd/cxx/tree/elements.ixx
@@ -45,20 +45,221 @@ namespace xsd
{
}
+ inline _type::
+ _type (const type& x, flags f, container* c)
+ : container_ (c)
+ {
+ if (x.content_.get () != 0)
+ content_ = x.content_->clone ();
+
+ if (x.dom_info_.get () != 0 && (f & flags::keep_dom))
+ {
+ dom_info_ = x.dom_info_->clone (*this, c);
+ }
+ }
+
+ inline const _type::dom_content_optional& _type::
+ dom_content () const
+ {
+ const content_type* c (content_.get ());
+
+ if (c == 0)
+ {
+ content_.reset (new dom_content_type);
+ c = content_.get ();
+ }
+
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<const dom_content_type*> (c) != 0);
+
+ return static_cast<const dom_content_type*> (c)->dom;
+ }
+
+ inline _type::dom_content_optional& _type::
+ dom_content ()
+ {
+ content_type* c (content_.get ());
+
+ if (c == 0)
+ {
+ content_.reset (new dom_content_type);
+ c = content_.get ();
+ }
+
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<dom_content_type*> (c) != 0);
+
+ return static_cast<dom_content_type*> (c)->dom;
+ }
+
+ inline void _type::
+ dom_content (const xercesc::DOMElement& e)
+ {
+ content_type* c (content_.get ());
+
+ if (c == 0)
+ content_.reset (new dom_content_type (e));
+ else
+ {
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<dom_content_type*> (c) != 0);
+ static_cast<dom_content_type*> (c)->dom.set (e);
+ }
+ }
+
+ inline void _type::
+ dom_content (xercesc::DOMElement* e)
+ {
+ content_type* c (content_.get ());
+
+ if (c == 0)
+ content_.reset (new dom_content_type (e));
+ else
+ {
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<dom_content_type*> (c) != 0);
+ static_cast<dom_content_type*> (c)->dom.set (e);
+ }
+ }
+
+ inline void _type::
+ dom_content (const dom_content_optional& d)
+ {
+ content_type* c (content_.get ());
+
+ if (c == 0)
+ content_.reset (new dom_content_type (d));
+ else
+ {
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<dom_content_type*> (c) != 0);
+ static_cast<dom_content_type*> (c)->dom = d;
+ }
+ }
+
+ inline const xercesc::DOMDocument& _type::
+ dom_content_document () const
+ {
+ const content_type* c (content_.get ());
+
+ if (c == 0)
+ {
+ content_.reset (new dom_content_type);
+ c = content_.get ();
+ }
+
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<const dom_content_type*> (c) != 0);
+
+ return *static_cast<const dom_content_type*> (c)->doc;
+ }
+
+ inline xercesc::DOMDocument& _type::
+ dom_content_document ()
+ {
+ content_type* c (content_.get ());
+
+ if (c == 0)
+ {
+ content_.reset (new dom_content_type);
+ c = content_.get ();
+ }
+
+ // Accessing non-DOM content via the DOM API.
+ //
+ assert (dynamic_cast<dom_content_type*> (c) != 0);
+
+ return *static_cast<dom_content_type*> (c)->doc;
+ }
+
+ inline bool _type::
+ null_content () const
+ {
+ return content_.get () == 0;
+ }
+
// simple_type
//
- template <typename B>
- inline simple_type<B>::
+ template <typename C, typename B>
+ inline simple_type<C, B>::
simple_type ()
{
}
- template <typename B>
- template <typename C>
- inline simple_type<B>::
- simple_type (const C*)
+ template <typename C, typename B>
+ inline simple_type<C, B>::
+ simple_type (const C* s)
+ {
+ this->content_.reset (new text_content_type (s));
+ }
+
+ template <typename C, typename B>
+ inline simple_type<C, B>::
+ simple_type (const std::basic_string<C>& s)
{
+ this->content_.reset (new text_content_type (s));
+ }
+
+ template <typename C, typename B>
+ inline const std::basic_string<C>& simple_type<C, B>::
+ text_content () const
+ {
+ const content_type* c (this->content_.get ());
+
+ if (c == 0)
+ {
+ this->content_.reset (new text_content_type);
+ c = this->content_.get ();
+ }
+
+ // Accessing non-text content via the text API.
+ //
+ assert (dynamic_cast<const text_content_type*> (c) != 0);
+
+ return static_cast<const text_content_type*> (c)->text;
+ }
+
+ template <typename C, typename B>
+ inline std::basic_string<C>& simple_type<C, B>::
+ text_content ()
+ {
+ content_type* c (this->content_.get ());
+
+ if (c == 0)
+ {
+ this->content_.reset (new text_content_type);
+ c = this->content_.get ();
+ }
+
+ // Accessing non-text content via the text API.
+ //
+ assert (dynamic_cast<text_content_type*> (c) != 0);
+
+ return static_cast<text_content_type*> (c)->text;
+ }
+
+ template <typename C, typename B>
+ inline void simple_type<C, B>::
+ text_content (const std::basic_string<C>& t)
+ {
+ content_type* c (this->content_.get ());
+
+ if (c == 0)
+ this->content_.reset (new text_content_type (t));
+ else
+ {
+ // Accessing non-text content via the text API.
+ //
+ assert (dynamic_cast<text_content_type*> (c) != 0);
+ static_cast<text_content_type*> (c)->text = t;
+ }
}
}
}
diff --git a/libxsd/xsd/cxx/tree/elements.txx b/libxsd/xsd/cxx/tree/elements.txx
index 7389a86..4a8ca6e 100644
--- a/libxsd/xsd/cxx/tree/elements.txx
+++ b/libxsd/xsd/cxx/tree/elements.txx
@@ -27,8 +27,8 @@ namespace xsd
// simple_type
//
- template <typename B>
- simple_type<B>::
+ template <typename C, typename B>
+ simple_type<C, B>::
simple_type (const simple_type& other,
flags f,
container* c)
@@ -36,8 +36,8 @@ namespace xsd
{
}
- template <typename B>
- simple_type<B>* simple_type<B>::
+ template <typename C, typename B>
+ simple_type<C, B>* simple_type<C, B>::
_clone (flags f, container* c) const
{
return new simple_type (*this, f, c);
diff --git a/libxsd/xsd/cxx/tree/iterator-adapter.hxx b/libxsd/xsd/cxx/tree/iterator-adapter.hxx
new file mode 100644
index 0000000..0a54604
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/iterator-adapter.hxx
@@ -0,0 +1,270 @@
+// file : xsd/cxx/tree/iterator-adapter.hxx
+// copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
+#define XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
+
+#include <cstddef> // std::ptrdiff_t
+#include <iterator> // std::iterator_traits
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Sun CC's <iterator> does not have iterator_traits. To overcome
+ // this, we will wrap std::iterator_traits into our own and also
+ // specialize it for pointer types. Since Sun CC uses pointer
+ // for vector::iterator, it will use the specialization and won't
+ // notice the std::iterator_traits.
+ //
+#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
+ template <typename I>
+ struct iterator_traits
+ {
+ typedef
+ typename std::iterator_traits<I>::iterator_category
+ iterator_category;
+
+ typedef
+ typename std::iterator_traits<I>::value_type
+ value_type;
+
+ typedef
+ typename std::iterator_traits<I>::difference_type
+ difference_type;
+ };
+#else
+ // The Pointer specialization does not work for reverse and
+ // set iterators. But these iterators are user-dfined types
+ // and have suitable typedefs that we can use.
+ //
+ template <typename I>
+ struct iterator_traits
+ {
+ typedef typename I::iterator_category iterator_category;
+ typedef typename I::value_type value_type;
+ typedef typename I::difference_type difference_type;
+ };
+
+ template <typename T>
+ struct iterator_traits<T*>
+ {
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef std::ptrdiff_t difference_type;
+ };
+#endif
+
+ // Iterator adapter for complex types. It expects I to point to
+ // a smart pointer-like object that has operator*() that returns
+ // a refernce to a type static_cast'able to T and get() that
+ // returns a pointer to a type static_cast'able to T.
+ //
+
+ template <typename I, typename T>
+ struct iterator_adapter
+ {
+ typedef T value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+
+ typedef
+ typename iterator_traits<I>::iterator_category
+ iterator_category;
+
+ typedef
+ typename iterator_traits<I>::difference_type
+ difference_type;
+
+
+ public:
+ iterator_adapter ()
+ : i_ () // i_ can be of a pointer type.
+ {
+ }
+
+ // Allow iterator to const_iterator conversion.
+ //
+ template <typename J, typename T2>
+ iterator_adapter (const iterator_adapter<J, T2>& j)
+ : i_ (j.base ())
+ {
+ }
+
+ explicit
+ iterator_adapter (const I& i)
+ : i_ (i)
+ {
+ }
+
+ public:
+ // Forward iterator requirements.
+ //
+ reference
+ operator* () const
+ {
+ return static_cast<reference> (**i_);
+ }
+
+ pointer
+ operator-> () const
+ {
+ return static_cast<pointer> (i_->get ());
+ }
+
+ iterator_adapter&
+ operator++ ()
+ {
+ ++i_;
+ return *this;
+ }
+
+ iterator_adapter
+ operator++ (int)
+ {
+ iterator_adapter r (*this);
+ ++i_;
+ return r;
+ }
+
+ // Bidirectional iterator requirements.
+ //
+ iterator_adapter&
+ operator-- ()
+ {
+ --i_;
+ return *this;
+ }
+
+ iterator_adapter
+ operator-- (int)
+ {
+ iterator_adapter r (*this);
+ --i_;
+ return r;
+ }
+
+ // Random access iterator requirements.
+ //
+ reference
+ operator[] (difference_type n) const
+ {
+ return static_cast<reference> (*(i_[n]));
+ }
+
+ iterator_adapter&
+ operator+= (difference_type n)
+ {
+ i_ += n;
+ return *this;
+ }
+
+ iterator_adapter
+ operator+ (difference_type n) const
+ {
+ return iterator_adapter (i_ + n);
+ }
+
+ iterator_adapter&
+ operator-= (difference_type n)
+ {
+ i_ -= n;
+ return *this;
+ }
+
+ iterator_adapter
+ operator- (difference_type n) const
+ {
+ return iterator_adapter (i_ - n);
+ }
+
+ public:
+ const I&
+ base () const
+ {
+ return i_;
+ }
+
+ private:
+ I i_;
+ };
+
+ // Note: We use different types for left- and right-hand-side
+ // arguments to allow comparison between iterator and const_iterator.
+ //
+
+ // Forward iterator requirements.
+ //
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator== (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () == j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator!= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () != j.base ();
+ }
+
+ // Random access iterator requirements
+ //
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator< (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () < j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator> (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () > j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator<= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () <= j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator>= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () >= j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline typename iterator_adapter<I, T1>::difference_type
+ operator- (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () - j.base ();
+ }
+
+ template <typename I, typename T>
+ inline iterator_adapter<I, T>
+ operator+ (typename iterator_adapter<I, T>::difference_type n,
+ const iterator_adapter<I, T>& i)
+ {
+ return iterator_adapter<I, T> (i.base () + n);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
diff --git a/libxsd/xsd/cxx/tree/list.hxx b/libxsd/xsd/cxx/tree/list.hxx
index 2b3b71e..d1fe907 100644
--- a/libxsd/xsd/cxx/tree/list.hxx
+++ b/libxsd/xsd/cxx/tree/list.hxx
@@ -10,7 +10,7 @@
#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMElement.hpp>
-#include <xsd/cxx/tree/elements.hxx> // tree::istream
+#include <xsd/cxx/tree/elements.hxx>
#include <xsd/cxx/tree/istream-fwd.hxx> // tree::istream
#include <xsd/cxx/tree/containers.hxx> // fundamental_p, sequence
diff --git a/libxsd/xsd/cxx/tree/parsing.txx b/libxsd/xsd/cxx/tree/parsing.txx
index 628b7fd..02aeda1 100644
--- a/libxsd/xsd/cxx/tree/parsing.txx
+++ b/libxsd/xsd/cxx/tree/parsing.txx
@@ -36,6 +36,9 @@ namespace xsd
_type (const xercesc::DOMElement& e, flags f, container* c)
: container_ (c)
{
+ if (f & flags::extract_content)
+ content_.reset (new dom_content_type (e));
+
if (f & flags::keep_dom)
dom_info_ = dom_info_factory::create (e, *this, c == 0);
}
@@ -44,6 +47,8 @@ namespace xsd
_type (const xercesc::DOMAttr& a, flags f, container* c)
: container_ (c)
{
+ // anyType cannot be an attribute type so no content extraction.
+
if (f & flags::keep_dom)
dom_info_ = dom_info_factory::create (a, *this);
}
@@ -56,33 +61,41 @@ namespace xsd
container* c)
: container_ (c) // List elements don't have associated DOM nodes.
{
+ // anyType cannot be a list element type so no content extraction.
}
// simple_type
//
- template <typename B>
- inline simple_type<B>::
+ template <typename C, typename B>
+ inline simple_type<C, B>::
simple_type (const xercesc::DOMElement& e, flags f, container* c)
- : B (e, f, c)
+ : B (e, (f & ~flags::extract_content), c)
{
+ if (f & flags::extract_content)
+ this->content_.reset (
+ new text_content_type (tree::text_content<C> (e)));
}
- template <typename B>
- inline simple_type<B>::
+ template <typename C, typename B>
+ inline simple_type<C, B>::
simple_type (const xercesc::DOMAttr& a, flags f, container* c)
- : B (a, f, c)
+ : B (a, (f & ~flags::extract_content), c)
{
+ if (f & flags::extract_content)
+ this->content_.reset (new text_content_type (
+ xml::transcode<C> (a.getValue ())));
}
- template <typename B>
- template <typename C>
- inline simple_type<B>::
+ template <typename C, typename B>
+ inline simple_type<C, B>::
simple_type (const std::basic_string<C>& s,
const xercesc::DOMElement* e,
flags f,
container* c)
- : B (s, e, f, c)
+ : B (s, e, (f & ~flags::extract_content), c)
{
+ if (f & flags::extract_content)
+ this->content_.reset (new text_content_type (s));
}
// fundamental_base
@@ -161,7 +174,7 @@ namespace xsd
}
// Individual items of the list have no DOM association. Therefore
- // I clear keep_dom from flags.
+ // we clear keep_dom from flags.
//
template <typename T, typename C, schema_type::value ST>
@@ -203,7 +216,6 @@ namespace xsd
return;
using std::basic_string;
- typedef typename sequence<T>::ptr ptr;
typedef typename basic_string<C>::size_type size_type;
const C* data (s.c_str ());
@@ -218,13 +230,12 @@ namespace xsd
if (j != basic_string<C>::npos)
{
- ptr r (
- new T (basic_string<C> (data + i, j - i),
- parent,
- f,
- this->container_));
-
- this->v_.push_back (r);
+ this->push_back (
+ traits<T, C, ST>::create (
+ basic_string<C> (data + i, j - i),
+ parent,
+ f,
+ this->container_));
i = bits::find_ns (data, size, j);
}
@@ -232,13 +243,12 @@ namespace xsd
{
// Last element.
//
- ptr r (
- new T (basic_string<C> (data + i, size - i),
- parent,
- f,
- this->container_));
-
- this->v_.push_back (r);
+ this->push_back (
+ traits<T, C, ST>::create (
+ basic_string<C> (data + i, size - i),
+ parent,
+ f,
+ this->container_));
break;
}
diff --git a/libxsd/xsd/cxx/tree/serialization.txx b/libxsd/xsd/cxx/tree/serialization.txx
index e6fea1f..055f603 100644
--- a/libxsd/xsd/cxx/tree/serialization.txx
+++ b/libxsd/xsd/cxx/tree/serialization.txx
@@ -91,9 +91,29 @@ namespace xsd
// Insertion operators for type.
//
inline void
- operator<< (xercesc::DOMElement& e, const type&)
+ operator<< (xercesc::DOMElement& e, const type& x)
{
xml::dom::clear<char> (e);
+
+ if (!x.null_content () && x.dom_content ().present ())
+ {
+ // Clone the contents of the element.
+ //
+ using namespace xercesc;
+
+ DOMDocument& doc (*e.getOwnerDocument ());
+ const DOMElement& se (x.dom_content ().get ());
+ DOMNamedNodeMap& sa (*se.getAttributes ());
+
+ for (XMLSize_t i (0), n (sa.getLength ()); i != n; ++i)
+ e.setAttributeNode (
+ static_cast<DOMAttr*> (doc.importNode (sa.item (i), true)));
+
+ for (DOMNode* sn (se.getFirstChild ());
+ sn != 0;
+ sn = sn->getNextSibling ())
+ e.appendChild (doc.importNode (sn, true));
+ }
}
inline void
@@ -109,23 +129,30 @@ namespace xsd
// Insertion operators for simple_type.
//
- template <typename B>
+ template <typename C, typename B>
inline void
- operator<< (xercesc::DOMElement& e, const simple_type<B>&)
+ operator<< (xercesc::DOMElement& e, const simple_type<C, B>& x)
{
- xml::dom::clear<char> (e);
+ if (x.null_content ())
+ xml::dom::clear<char> (e);
+ else
+ e << x.text_content ();
}
- template <typename B>
+ template <typename C, typename B>
inline void
- operator<< (xercesc::DOMAttr&, const simple_type<B>&)
+ operator<< (xercesc::DOMAttr& a, const simple_type<C, B>& x)
{
+ if (!x.null_content ())
+ a << x.text_content ();
}
template <typename C, typename B>
inline void
- operator<< (list_stream<C>&, const simple_type<B>&)
+ operator<< (list_stream<C>& ls, const simple_type<C, B>& x)
{
+ if (!x.null_content ())
+ ls << x.text_content ();
}
// Insertion operators for list.
diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx
index c79cdb6..ef65ef2 100644
--- a/libxsd/xsd/cxx/tree/std-ostream-map.txx
+++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx
@@ -24,7 +24,7 @@ namespace xsd
&inserter_impl<C, type>,
false);
- typedef simple_type<type> simple_type;
+ typedef simple_type<C, type> simple_type;
register_type (
typeid (simple_type),
&inserter_impl<C, simple_type>,
diff --git a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx
index 071d186..9a8f976 100644
--- a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx
+++ b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx
@@ -24,6 +24,7 @@ namespace xsd
inline std::basic_ostream<C>&
operator<< (std::basic_ostream<C>& os, const type&)
{
+ // Not printing DOM content even if it's there.
return os;
}
@@ -32,8 +33,11 @@ namespace xsd
//
template <typename C, typename B>
inline std::basic_ostream<C>&
- operator<< (std::basic_ostream<C>& os, const simple_type<B>&)
+ operator<< (std::basic_ostream<C>& os, const simple_type<C, B>& x)
{
+ if (!x.null_content ())
+ os << x.text_content ();
+
return os;
}
diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx
index 646ef83..61dd306 100644
--- a/libxsd/xsd/cxx/tree/stream-extraction-map.txx
+++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx
@@ -30,7 +30,7 @@ namespace xsd
&extractor_impl<S, type>,
false);
- typedef simple_type<type> simple_type;
+ typedef simple_type<C, type> simple_type;
register_type (
qualified_name (bits::any_simple_type<C> (), xsd),
&extractor_impl<S, simple_type>,
diff --git a/libxsd/xsd/cxx/tree/stream-extraction.hxx b/libxsd/xsd/cxx/tree/stream-extraction.hxx
index b55afa0..ee39bcc 100644
--- a/libxsd/xsd/cxx/tree/stream-extraction.hxx
+++ b/libxsd/xsd/cxx/tree/stream-extraction.hxx
@@ -28,12 +28,18 @@ namespace xsd
// simple_type
//
- template <typename B>
+ template <typename C, typename B>
template <typename S>
- inline simple_type<B>::
+ inline simple_type<C, B>::
simple_type (istream<S>& s, flags f, container* c)
- : type (s, f, c)
+ : type (s, f & ~flags::extract_content, c)
{
+ if (f & flags::extract_content)
+ {
+ std::basic_string<C> t;
+ s >> t;
+ this->content_.reset (new text_content_type (t));
+ }
}
// fundamental_base
@@ -65,9 +71,7 @@ namespace xsd
this->reserve (size);
while (size--)
- {
- this->push_back (XSD_AUTO_PTR<T> (new T (s, f, c)));
- }
+ this->push_back (traits<T, C, ST>::create (s, f, c));
}
}
diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx
index 1550826..78fbacb 100644
--- a/libxsd/xsd/cxx/tree/stream-insertion-map.txx
+++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx
@@ -31,7 +31,7 @@ namespace xsd
&inserter_impl<S, type>,
false);
- typedef simple_type<type> simple_type;
+ typedef simple_type<C, type> simple_type;
register_type (
typeid (simple_type),
qualified_name (bits::any_simple_type<C> (), xsd),
diff --git a/libxsd/xsd/cxx/tree/stream-insertion.hxx b/libxsd/xsd/cxx/tree/stream-insertion.hxx
index 7f1f5df..b04846f 100644
--- a/libxsd/xsd/cxx/tree/stream-insertion.hxx
+++ b/libxsd/xsd/cxx/tree/stream-insertion.hxx
@@ -23,15 +23,19 @@ namespace xsd
inline ostream<S>&
operator<< (ostream<S>& s, const type&)
{
+ // Not saving DOM content even if it's there.
return s;
}
// simple_type
//
- template <typename S, typename B>
+ template <typename S, typename C, typename B>
inline ostream<S>&
- operator<< (ostream<S>& s, const simple_type<B>&)
+ operator<< (ostream<S>& s, const simple_type<C, B>& x)
{
+ if (!x.null_content ())
+ s << x.text_content ();
+
return s;
}
diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx
index 8ccbc63..e1fe0cc 100644
--- a/libxsd/xsd/cxx/tree/type-factory-map.txx
+++ b/libxsd/xsd/cxx/tree/type-factory-map.txx
@@ -37,7 +37,7 @@ namespace xsd
&factory_impl<type>,
false);
- typedef simple_type<type> simple_type;
+ typedef simple_type<C, type> simple_type;
register_type (
qualified_name (bits::any_simple_type<C> (), xsd),
&factory_impl<simple_type>,
diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx
index 353ccae..dd47a00 100644
--- a/libxsd/xsd/cxx/tree/type-serializer-map.txx
+++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx
@@ -38,7 +38,7 @@ namespace xsd
&serializer_impl<type>,
false);
- typedef simple_type<type> simple_type;
+ typedef simple_type<C, type> simple_type;
register_type (
typeid (simple_type),
qualified_name (bits::any_simple_type<C> (), xsd),
diff --git a/libxsd/xsd/cxx/tree/types.hxx b/libxsd/xsd/cxx/tree/types.hxx
index 61a1e1a..288a291 100644
--- a/libxsd/xsd/cxx/tree/types.hxx
+++ b/libxsd/xsd/cxx/tree/types.hxx
@@ -271,6 +271,29 @@ namespace xsd
}
};
+ /**
+ * @brief %string comparison operator.
+ *
+ * @return True if the strings are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator== (const string<C, B>& a, const string<C, B>& b)
+ {
+ return static_cast<const std::basic_string<C>&> (a) == b;
+ }
+
+ /**
+ * @brief %string comparison operator.
+ *
+ * @return True if the strings are not equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator!= (const string<C, B>& a, const string<C, B>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema normalizedString
@@ -1119,6 +1142,31 @@ namespace xsd
//@}
};
+ /**
+ * @brief %nmtokens comparison operator.
+ *
+ * @return True if the lists of nmtokens are equal, false otherwise.
+ */
+ template <typename C, typename B, typename nmtoken>
+ inline bool
+ operator== (const nmtokens<C, B, nmtoken>& a,
+ const nmtokens<C, B, nmtoken>& b)
+ {
+ return static_cast<const list<nmtoken, C>&> (a) == b;
+ }
+
+ /**
+ * @brief %nmtokens comparison operator.
+ *
+ * @return True if the lists of nmtokens are not equal, false otherwise.
+ */
+ template <typename C, typename B, typename nmtoken>
+ inline bool
+ operator!= (const nmtokens<C, B, nmtoken>& a,
+ const nmtokens<C, B, nmtoken>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema Name built-in
@@ -2575,6 +2623,29 @@ namespace xsd
//@}
};
+ /**
+ * @brief %idrefs comparison operator.
+ *
+ * @return True if the lists of idrefs are equal, false otherwise.
+ */
+ template <typename C, typename B, typename idref>
+ inline bool
+ operator== (const idrefs<C, B, idref>& a, const idrefs<C, B, idref>& b)
+ {
+ return static_cast<const list<idref, C>&> (a) == b;
+ }
+
+ /**
+ * @brief %idrefs comparison operator.
+ *
+ * @return True if the lists of idrefs are not equal, false otherwise.
+ */
+ template <typename C, typename B, typename idref>
+ inline bool
+ operator!= (const idrefs<C, B, idref>& a, const idrefs<C, B, idref>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema anyURI built-in
@@ -2811,6 +2882,29 @@ namespace xsd
friend class qname;
};
+ /**
+ * @brief %uri comparison operator.
+ *
+ * @return True if the uris are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator== (const uri<C, B>& a, const uri<C, B>& b)
+ {
+ return static_cast<const std::basic_string<C>&> (a) == b;
+ }
+
+ /**
+ * @brief %uri comparison operator.
+ *
+ * @return True if the uris are not equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator!= (const uri<C, B>& a, const uri<C, B>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema QName built-in
@@ -3211,6 +3305,29 @@ namespace xsd
decode (const XMLCh*);
};
+ /**
+ * @brief %base64_binary comparison operator.
+ *
+ * @return True if the binaries are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator== (const base64_binary<C, B>& a, const base64_binary<C, B>& b)
+ {
+ return static_cast<const buffer<C>&> (a) == b;
+ }
+
+ /**
+ * @brief %base64_binary comparison operator.
+ *
+ * @return True if the binaries are not equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator!= (const base64_binary<C, B>& a, const base64_binary<C, B>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema hexBinary
@@ -3404,6 +3521,29 @@ namespace xsd
decode (const XMLCh*);
};
+ /**
+ * @brief %hex_binary comparison operator.
+ *
+ * @return True if the binaries are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator== (const hex_binary<C, B>& a, const hex_binary<C, B>& b)
+ {
+ return static_cast<const buffer<C>&> (a) == b;
+ }
+
+ /**
+ * @brief %hex_binary comparison operator.
+ *
+ * @return True if the binaries are not equal, false otherwise.
+ */
+ template <typename C, typename B>
+ inline bool
+ operator!= (const hex_binary<C, B>& a, const hex_binary<C, B>& b)
+ {
+ return !(a == b);
+ }
/**
* @brief Class corresponding to the XML Schema ENTITY built-in
@@ -3768,6 +3908,32 @@ namespace xsd
container* c = 0);
//@}
};
+
+ /**
+ * @brief %entities comparison operator.
+ *
+ * @return True if the lists of entities are equal, false otherwise.
+ */
+ template <typename C, typename B, typename entity>
+ inline bool
+ operator== (const entities<C, B, entity>& a,
+ const entities<C, B, entity>& b)
+ {
+ return static_cast<const list<entity, C>&> (a) == b;
+ }
+
+ /**
+ * @brief %entities comparison operator.
+ *
+ * @return True if the lists of entities are not equal, false otherwise.
+ */
+ template <typename C, typename B, typename entity>
+ inline bool
+ operator!= (const entities<C, B, entity>& a,
+ const entities<C, B, entity>& b)
+ {
+ return !(a == b);
+ }
}
}
}
diff --git a/libxsd/xsd/cxx/xml/string.hxx b/libxsd/xsd/cxx/xml/string.hxx
index dbc78b4..9f4767b 100644
--- a/libxsd/xsd/cxx/xml/string.hxx
+++ b/libxsd/xsd/cxx/xml/string.hxx
@@ -56,21 +56,16 @@ namespace xsd
public :
template <typename C>
string (const std::basic_string<C>& s)
- : s_ (transcode_to_xmlch<C> (s))
- {
- }
+ : s_ (transcode_to_xmlch<C> (s)) {}
template <typename C>
- string (const C* s)
- : s_ (transcode_to_xmlch<C> (s))
- {
- }
+ string (const C* s): s_ (transcode_to_xmlch<C> (s)) {}
const XMLCh*
- c_str () const
- {
- return s_.get ();
- }
+ c_str () const {return s_.get ();}
+
+ XMLCh*
+ release () {return s_.release ();}
private:
string (const string&);
diff --git a/tests/cxx/tree/any-type/driver.cxx b/tests/cxx/tree/any-type/driver.cxx
new file mode 100644
index 0000000..1ac5274
--- /dev/null
+++ b/tests/cxx/tree/any-type/driver.cxx
@@ -0,0 +1,145 @@
+// file : tests/cxx/tree/any-type/driver.cxx
+// copyright : Copyright (c) 2006-2014 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test anyType and anySimpleType content extraction.
+//
+
+#include <memory> // std::auto_ptr/unique_ptr
+#include <utility> // std::move
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "test.hxx" // Get XSD_CXX11 defined.
+
+#include <xsd/cxx/xml/string.hxx>
+
+using namespace std;
+using namespace test;
+using namespace xercesc;
+
+namespace xml = xsd::cxx::xml;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ // Test parsing
+ //
+ XSD_AUTO_PTR<type> r (root (argv[1]));
+
+ // Test API.
+ //
+ {
+ assert (type::a_default_value ().text_content () == "default value");
+ }
+
+ {
+ xml_schema::simple_type x ("fox");
+ assert (x.text_content () == "fox");
+ x.text_content ("foo");
+ assert (x.text_content () == "foo");
+ x.text_content ().clear ();
+ assert (x.text_content () == "");
+ x.text_content () = "baz";
+ r->s ().push_back (x);
+ }
+
+ {
+ xml_schema::type x;
+
+ DOMDocument& doc (x.dom_content_document ());
+
+ // Copy.
+ //
+ DOMElement* e (doc.createElement (xml::string ("dummy").c_str ()));
+ e->setAttribute (xml::string ("x").c_str (),
+ xml::string ("foo").c_str ());
+ e->setTextContent (xml::string ("data").c_str ());
+ x.dom_content ().set (*e);
+ e->release ();
+
+ r->t ().push_back (x);
+ }
+
+ {
+ XSD_AUTO_PTR<xml_schema::type> x (new xml_schema::type);
+
+ DOMDocument& doc (x->dom_content_document ());
+
+ // Assume ownership.
+ //
+ DOMElement* e (doc.createElement (xml::string ("dummy").c_str ()));
+ e->setAttribute (xml::string ("x").c_str (),
+ xml::string ("foo").c_str ());
+ e->setTextContent (xml::string ("data").c_str ());
+ x->dom_content ().set (e);
+
+#ifdef XSD_CXX11
+ r->t ().push_back (std::move (x));
+#else
+ r->t ().push_back (x);
+#endif
+ }
+
+ // Test printing.
+ //
+ cout << *r << endl
+ << endl;
+
+ // Test serialization.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["t"].name = "test";
+ map["t"].schema = "test.xsd";
+ map["o"].name = "other";
+
+ stringstream iostr;
+ root (iostr, *r, map);
+
+ cout << iostr.str () << endl
+ << endl;
+
+ {
+ XSD_AUTO_PTR<type> r1 (root (iostr, argv[1]));
+
+ // Xerces-C++ mis-indentation of mixed content messes this up.
+ // assert (*r == *r);
+
+ stringstream iostr;
+ root (iostr, *r1, map);
+
+ cout << iostr.str () << endl
+ << endl;
+ }
+
+ // Test comparison.
+ //
+ assert (*r == *r);
+
+ // Test copy c-tor.
+ //
+ type copy (*r);
+ assert (copy == *r);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+}
diff --git a/tests/cxx/tree/any-type/makefile b/tests/cxx/tree/any-type/makefile
new file mode 100644
index 0000000..1d0590f
--- /dev/null
+++ b/tests/cxx/tree/any-type/makefile
@@ -0,0 +1,87 @@
+# file : tests/cxx/tree/any-type/makefile
+# copyright : Copyright (c) 2006-2014 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(out_base) -I$(src_base) -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+$(gen): xsd_options += --generate-any-type --generate-serialization \
+--generate-ostream --generate-comparison
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep),$(obj),$(gen))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+
+$(call include,$(bld_root)/cxx/standard.make) # cxx_standard
+ifdef cxx_standard
+$(gen): xsd_options += --std $(cxx_standard)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+endif
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/any-type/output b/tests/cxx/tree/any-type/output
new file mode 100644
index 0000000..580e7db
--- /dev/null
+++ b/tests/cxx/tree/any-type/output
@@ -0,0 +1,73 @@
+
+t:
+t:
+t:
+t:
+t:
+t:
+t:
+t:
+s:
+s: simple
+s: baz
+l: one two three
+a: any simple content
+
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test" a="any simple content" xmlns:o="other" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd">
+ <t/>
+ <t x="x"/>
+ <t>any</t>
+ <t x="x">any</t>
+ <t o:y="y" x="x">
+ <n1>
+ <n2>nested 1</n2>
+ <n2>nested 2</n2>
+ </n1>
+ <o:n2 o:x="x">more</o:n2>
+ </t><t x="x">
+ <n1>mi
+ <n2>nested 1</n2>x
+ <n2>nested 2</n2>ed
+ </n1>content
+ </t>
+ <t x="foo">data</t>
+ <t x="foo">data</t>
+ <s/>
+ <s>simple</s>
+ <s>baz</s>
+ <l>one two three</l>
+</t:root>
+
+
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test" a="any simple content" xmlns:o="other" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd">
+ <t/>
+ <t x="x"/>
+ <t>any</t>
+ <t x="x">any</t>
+ <t o:y="y" x="x">
+ <n1>
+ <n2>nested 1</n2>
+ <n2>nested 2</n2>
+ </n1>
+ <o:n2 o:x="x">more</o:n2>
+ </t><t x="x">
+ <n1>mi
+
+ <n2>nested 1</n2>x
+
+ <n2>nested 2</n2>ed
+
+ </n1>content
+
+ </t>
+ <t x="foo">data</t>
+ <t x="foo">data</t>
+ <s/>
+ <s>simple</s>
+ <s>baz</s>
+ <l>one two three</l>
+</t:root>
+
+
diff --git a/tests/cxx/tree/any-type/test.xml b/tests/cxx/tree/any-type/test.xml
new file mode 100644
index 0000000..7c9035a
--- /dev/null
+++ b/tests/cxx/tree/any-type/test.xml
@@ -0,0 +1,26 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd"
+
+ a="any simple content">
+
+ <t/>
+ <t x="x"/>
+ <t>any</t>
+ <t x="x">any</t>
+ <t x="x" o:y="y">
+ <n1>
+ <n2>nested 1</n2>
+ <n2>nested 2</n2>
+ </n1>
+ <o:n2 o:x="x">more</o:n2>
+ </t>
+ <t x="x"><n1>mi<n2>nested 1</n2>x<n2>nested 2</n2>ed</n1>content</t>
+
+ <s/>
+ <s>simple</s>
+
+ <l>one two three</l>
+
+</t:root>
diff --git a/tests/cxx/tree/any-type/test.xsd b/tests/cxx/tree/any-type/test.xsd
new file mode 100644
index 0000000..37dcc8d
--- /dev/null
+++ b/tests/cxx/tree/any-type/test.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="any-list">
+ <!--Not allowed? list itemType="anySimpleType"/-->
+ <list itemType="string"/>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="t" type="anyType" maxOccurs="unbounded"/>
+ <element name="s" type="anySimpleType" maxOccurs="unbounded"/>
+ <element name="l" type="t:any-list" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="a" type="anySimpleType" default="default value"/>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+</schema>
diff --git a/tests/cxx/tree/binary/cdr/driver.cxx b/tests/cxx/tree/binary/cdr/driver.cxx
index 65c88fa..a2d7195 100644
--- a/tests/cxx/tree/binary/cdr/driver.cxx
+++ b/tests/cxx/tree/binary/cdr/driver.cxx
@@ -127,6 +127,14 @@ main (int argc, char* argv[])
assert (r->time () == c->time ());
assert (r->date_time () == c->date_time ());
assert (r->duration () == c->duration ());
+
+ // anySimpleType
+ //
+ assert (!r->any_simple_type_attr ().text_content ().empty ());
+ assert (r->any_simple_type_attr () == c->any_simple_type_attr ());
+
+ assert (!r->any_simple_type ().text_content ().empty ());
+ assert (r->any_simple_type () == c->any_simple_type ());
}
catch (xml_schema::exception const& e)
{
diff --git a/tests/cxx/tree/binary/cdr/makefile b/tests/cxx/tree/binary/cdr/makefile
index 9613841..eb80d35 100644
--- a/tests/cxx/tree/binary/cdr/makefile
+++ b/tests/cxx/tree/binary/cdr/makefile
@@ -37,7 +37,7 @@ gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
$(gen): xsd_options += --generate-insertion ACE_OutputCDR \
---generate-extraction ACE_InputCDR
+--generate-extraction ACE_InputCDR --generate-comparison
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep),$(obj),$(gen))
diff --git a/tests/cxx/tree/binary/cdr/test.xml b/tests/cxx/tree/binary/cdr/test.xml
index 928b4cf..5cedd98 100644
--- a/tests/cxx/tree/binary/cdr/test.xml
+++ b/tests/cxx/tree/binary/cdr/test.xml
@@ -1,6 +1,7 @@
<t:root xmlns:t="test"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="test test.xsd">
+ xsi:schemaLocation="test test.xsd"
+ any_simple_type_attr="any simple content">
<list>1 2 3</list>
@@ -87,5 +88,6 @@
<year_month>2001-11+02:00</year_month>
<time>21:32:52+02:00</time>
+ <any_simple_type>any simple content in element</any_simple_type>
</t:root>
diff --git a/tests/cxx/tree/binary/cdr/test.xsd b/tests/cxx/tree/binary/cdr/test.xsd
index e593f64..0629e94 100644
--- a/tests/cxx/tree/binary/cdr/test.xsd
+++ b/tests/cxx/tree/binary/cdr/test.xsd
@@ -112,7 +112,10 @@
<element name="year" type="gYear"/>
<element name="year_month" type="gYearMonth"/>
<element name="time" type="time"/>
+
+ <element name="any_simple_type" type="anySimpleType"/>
</sequence>
+ <attribute name="any_simple_type_attr" type="anySimpleType" use="required"/>
</complexType>
<element name="root" type="t:type"/>
diff --git a/tests/cxx/tree/binary/polymorphic/makefile b/tests/cxx/tree/binary/polymorphic/makefile
index f9ddf67..05c5186 100644
--- a/tests/cxx/tree/binary/polymorphic/makefile
+++ b/tests/cxx/tree/binary/polymorphic/makefile
@@ -37,7 +37,8 @@ gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
$(gen): xsd_options += --generate-polymorphic --root-element-last \
---generate-insertion ACE_OutputCDR --generate-extraction ACE_InputCDR
+--generate-insertion ACE_OutputCDR --generate-extraction ACE_InputCDR \
+ --generate-comparison
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep),$(obj),$(gen))
diff --git a/tests/cxx/tree/binary/xdr/driver.cxx b/tests/cxx/tree/binary/xdr/driver.cxx
index ddc196d..623a953 100644
--- a/tests/cxx/tree/binary/xdr/driver.cxx
+++ b/tests/cxx/tree/binary/xdr/driver.cxx
@@ -171,6 +171,14 @@ main (int argc, char* argv[])
assert (r->year () == c->year ());
assert (r->year_month () == c->year_month ());
assert (r->time () == c->time ());
+
+ // anySimpleType
+ //
+ assert (!r->any_simple_type_attr ().text_content ().empty ());
+ assert (r->any_simple_type_attr () == c->any_simple_type_attr ());
+
+ assert (!r->any_simple_type ().text_content ().empty ());
+ assert (r->any_simple_type () == c->any_simple_type ());
}
catch (xml_schema::exception const& e)
{
diff --git a/tests/cxx/tree/binary/xdr/makefile b/tests/cxx/tree/binary/xdr/makefile
index 184c5d2..2994134 100644
--- a/tests/cxx/tree/binary/xdr/makefile
+++ b/tests/cxx/tree/binary/xdr/makefile
@@ -32,7 +32,8 @@ genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
gen := $(addprefix $(out_base)/,$(genf))
$(gen): xsd := $(out_root)/xsd/xsd
-$(gen): xsd_options += --generate-insertion XDR --generate-extraction XDR
+$(gen): xsd_options += --generate-insertion XDR --generate-extraction XDR \
+--generate-comparison
$(gen): $(out_root)/xsd/xsd
$(call include-dep,$(dep),$(obj),$(gen))
diff --git a/tests/cxx/tree/binary/xdr/test.xml b/tests/cxx/tree/binary/xdr/test.xml
index 928b4cf..5cedd98 100644
--- a/tests/cxx/tree/binary/xdr/test.xml
+++ b/tests/cxx/tree/binary/xdr/test.xml
@@ -1,6 +1,7 @@
<t:root xmlns:t="test"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="test test.xsd">
+ xsi:schemaLocation="test test.xsd"
+ any_simple_type_attr="any simple content">
<list>1 2 3</list>
@@ -87,5 +88,6 @@
<year_month>2001-11+02:00</year_month>
<time>21:32:52+02:00</time>
+ <any_simple_type>any simple content in element</any_simple_type>
</t:root>
diff --git a/tests/cxx/tree/binary/xdr/test.xsd b/tests/cxx/tree/binary/xdr/test.xsd
index e593f64..0629e94 100644
--- a/tests/cxx/tree/binary/xdr/test.xsd
+++ b/tests/cxx/tree/binary/xdr/test.xsd
@@ -112,7 +112,10 @@
<element name="year" type="gYear"/>
<element name="year_month" type="gYearMonth"/>
<element name="time" type="time"/>
+
+ <element name="any_simple_type" type="anySimpleType"/>
</sequence>
+ <attribute name="any_simple_type_attr" type="anySimpleType" use="required"/>
</complexType>
<element name="root" type="t:type"/>
diff --git a/tests/cxx/tree/compilation/driver.cxx b/tests/cxx/tree/compilation/driver.cxx
index c396ec5..c2e6298 100644
--- a/tests/cxx/tree/compilation/driver.cxx
+++ b/tests/cxx/tree/compilation/driver.cxx
@@ -13,7 +13,7 @@
using namespace std;
using namespace test;
-template class xsd::cxx::tree::simple_type<xml_schema::type>;
+template class xsd::cxx::tree::simple_type<char, xml_schema::type>;
// String types.
//
diff --git a/tests/cxx/tree/makefile b/tests/cxx/tree/makefile
index cd081e8..7fd9f63 100644
--- a/tests/cxx/tree/makefile
+++ b/tests/cxx/tree/makefile
@@ -5,6 +5,7 @@
include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
tests := \
+any-type \
built-in \
chameleon \
comparison \
diff --git a/xsd/cxx/tree/fundamental-header.hxx b/xsd/cxx/tree/fundamental-header.hxx
index 1145c0c..925d65e 100644
--- a/xsd/cxx/tree/fundamental-header.hxx
+++ b/xsd/cxx/tree/fundamental-header.hxx
@@ -241,7 +241,7 @@ namespace CXX
traverse (SemanticGraph::AnySimpleType& t)
{
simple_type_ = built_in_type (
- t, L"::xsd::cxx::tree::simple_type< ", type_);
+ t, L"::xsd::cxx::tree::simple_type< " + char_type + L", ", type_);
if (doxygen)
os << "/**" << endl
diff --git a/xsd/cxx/tree/options.cli b/xsd/cxx/tree/options.cli
index 026e4a1..f1b343a 100644
--- a/xsd/cxx/tree/options.cli
+++ b/xsd/cxx/tree/options.cli
@@ -170,6 +170,13 @@ namespace CXX
this option."
};
+ bool --generate-any-type
+ {
+ "Extract and store content of the XML Schema \cb{anyType} type as a
+ DOM fragment. Note that you need to initialize the Xerces-C++ runtime
+ if you are using this option."
+ };
+
NarrowStrings --generate-insertion
{
"<os>",
diff --git a/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/cxx/tree/stream-extraction-source.cxx
index a1ca4bc..ceb56c1 100644
--- a/xsd/cxx/tree/stream-extraction-source.cxx
+++ b/xsd/cxx/tree/stream-extraction-source.cxx
@@ -321,6 +321,7 @@ namespace CXX
SemanticGraph::Type& t (e.type ());
String type (etype (e));
+ String tr (etraits (e)); // traits type name
bool fund (false);
{
@@ -389,8 +390,8 @@ namespace CXX
}
else
{
- os << auto_ptr << "< " << type << " > r (new " << type <<
- " (s, f, this));";
+ os << auto_ptr << "< " << type << " > r (" << endl
+ << tr << "::create (s, f, this));";
}
os << "c.push_back (" << r << ");"
@@ -438,8 +439,8 @@ namespace CXX
}
else
{
- os << auto_ptr << "< " << type << " > r (new " << type <<
- " (s, f, this));";
+ os << auto_ptr << "< " << type << " > r (" << endl
+ << tr << "::create (s, f, this));";
}
os << "this->" << member << ".set (" << r << ");"
@@ -482,8 +483,8 @@ namespace CXX
}
else
{
- os << auto_ptr << "< " << type << " > r (new " << type <<
- " (s, f, this));";
+ os << auto_ptr << "< " << type << " > r (" << endl
+ << tr << "::create (s, f, this));";
}
os << "this->" << member << ".set (" << r << ");"
@@ -507,6 +508,7 @@ namespace CXX
{
String const& member (emember (a));
String type (etype (a));
+ String tr (etraits (a)); // traits type name
bool fund (false);
{
@@ -530,8 +532,8 @@ namespace CXX
}
else
{
- os << "this->" << member << ".set (" << auto_ptr << "< " <<
- type << " > (new " << type << " (s, f, this)));";
+ os << "this->" << member << ".set (" << tr <<
+ "::create (s, f, this));";
}
os << "}" // if (p)
@@ -549,8 +551,8 @@ namespace CXX
}
else
{
- os << "this->" << member << ".set (" << auto_ptr << "< " <<
- type << " > (new " << type << " (s, f, this)));";
+ os << "this->" << member << ".set (" << tr <<
+ "::create (s, f, this));";
}
os << "}";
diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx
index e6c2411..f0c3560 100644
--- a/xsd/cxx/tree/tree-header.cxx
+++ b/xsd/cxx/tree/tree-header.cxx
@@ -291,6 +291,22 @@ namespace CXX
<< "~" << name << " ();";
os << "};";
+
+ // Comparison operators.
+ //
+ if (options.generate_comparison ())
+ {
+ os << inst_exp
+ << "bool" << endl
+ << "operator== (const " << name << "&, const " << name << "&);"
+ << endl;
+
+ os << inst_exp
+ << "bool" << endl
+ << "operator!= (const " << name << "&, const " << name << "&);"
+ << endl
+ << endl;
+ }
}
private:
diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx
index e6ed756..500ee73 100644
--- a/xsd/cxx/tree/tree-inline.cxx
+++ b/xsd/cxx/tree/tree-inline.cxx
@@ -82,6 +82,28 @@ namespace CXX
<< " " << base_type << " (o, f, this)"
<< "{"
<< "}";
+
+ // Comparison operators.
+ //
+ if (options.generate_comparison ())
+ {
+ os << inl
+ << "bool" << endl
+ << "operator== (const " << name << "& x, " <<
+ "const " << name << "& y)"
+ << "{"
+ << "const " << base_type << "& bx (x);"
+ << "return bx == y;"
+ << "}";
+
+ os << inl
+ << "bool" << endl
+ << "operator!= (const " << name << "& x, " <<
+ "const " << name << "& y)"
+ << "{"
+ << "return !(x == y);"
+ << "}";
+ }
}
private:
diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx
index 110cb25..9524463 100644
--- a/xsd/cxx/tree/tree-source.cxx
+++ b/xsd/cxx/tree/tree-source.cxx
@@ -756,7 +756,13 @@ namespace CXX
if (!fund)
{
os << auto_ptr << "< " << type << " > r (" << endl
- << tr << "::create (i, f, this));"
+ << tr << "::create (i, f";
+
+ if (t.is_a<SemanticGraph::AnyType> () &&
+ options.generate_any_type ())
+ os << " | " << flags_type << "::extract_content";
+
+ os << ", this));"
<< endl;
}
}