[xsd-users] BUG in generated code: Custom list type's
getDefaultValue() returns twice the number of elements as its defined
fixed size
Boris Kolpackov
boris at codesynthesis.com
Wed Feb 20 07:55:01 EST 2019
Delker, Stefan <Stefan.Delker at kmweg.de> writes:
> <simpleType name="DISEntityType">
> <restriction>
> <simpleType>
> <list itemType="unsignedShort"/>
> </simpleType>
> <length value="7" fixed="true"/>
> </restriction>
> </simpleType>
>
> <element name="entityType" type="DISEntityType" minOccurs="0" default="0 0 0 0 0 0 0"/>
>
> Our custom type implementation initializes the type by default having
> 7 elements, to guarantee all data is accessible:
>
> class DISEntityType : public DISEntityType_impl
> {
> public:
>
> DISEntityType () : DISEntityType_impl(DISEntityType_base(7, 0)) {}
>
> inline uint32_t getKind() const { return uint32_t((*this)[0]); }
>
> [...]
>
> }
>
> From debugging the generated code, the default constructor already
> initializes the list with 7 elements.
>
> The _xsd_entityType_default_value_init () adds seven elements to the
> default constructed object using (7 times):
>
> {
> ::xml_schema::UnsignedShort tmp (0U);
> r.push_back (tmp);
> }
>
> Is this actually a bug or are we misusing some feature of XSD?
I believe the problem is in your mapping of the DISEntityType XML
Schema type to the DISEntityType C++ class. It does not reflect
what the schema says, which is, "a valid instance of DISEntityType
must contain 7 elements" (<length value="7" fixed="true"/>). It
does not say that "a valid instance of type DISEntityType always
contains 7 zeroes". In particular, the following would be valid
per the schema definition of DISEntityType:
<element name="entityType2" type="DISEntityType" minOccurs="0" default="1 1 1 1 1 1 1"/>
In a sense, a more accurate mapping would have been something along
these lines:
class DISEntityType : public DISEntityType_impl
{
public:
DISEntityType () {}
inline uint32_t getKind() const
{
assert (size () == 7);
return uint32_t((*this)[0]);
}
[...]
};
If you want to continue using your current mapping then one (admittedly
hackish) way to make it work would be to re-define push_back() (which
is pretty useless in your case anyway) along these lines:
class DISEntityType : public DISEntityType_impl
{
public:
[...]
inline void push_back (unsigned short x)
{
if (size () == 7)
clear ();
DISEntityType_impl::push_back (x);
}
};
More information about the xsd-users
mailing list