[xsd-users] Specifying Element content for "anyType" Elements
Jan Klimke
jan.klimke at hpi.uni-potsdam.de
Thu Sep 25 13:25:19 EDT 2008
Thank you for your detailed answer. Unfortunately i did not have time to
try it until today. THe customization works fine. I am able to specify
the name of the binarycomaprison element.
But one big problem remains. I am currently doing the following in my code:
schemas::coll::Boolean& b = schemas::coll::Boolean(true);
xml_schema::string& name = xml_schema::string("coll:isActive");
ogc::LiteralType& lit = (ogc::LiteralType&)b;
ogc::PropertyNameType& pname = (ogc::PropertyNameType&)name;
ogc::BinaryComparisonOpType& isEqualActive =
ogc::BinaryComparisonOpType();
ogc::BinaryComparisonOpType::expression_sequence& expressions =
ogc::BinaryComparisonOpType::expression_sequence();
expressions.push_back(pname);
expressions.push_back(lit);
isEqualActive.expression(expressions);
filter.comparisonOps(isEqualActive);
filter.setOpName(std::string("PropertyIsEqualTo"));
When i serialize the filter object the PropertyNameType and Literal
object are serialized as expression elements, but they should be
PropertyName and Literal elements to be accepted by the service i plan
to call.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs"
outputFormat="text/xml; subtype=gml/3.1.1" resultType="results"
service="WFS" version="1.1.0"
xmlns:coll="http://www.hpi.uni-potsdam.de/schemas/coll"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs
http://localhost:8080/schemas/wfs.xsd">
<wfs:Query typeName="coll:CollaborationSession"
xmlns:p1="http://www.opengis.n
et/ogc">
<p1:Filter>
<PropertyIsEqualTo xmlns="http://www.opengis.net/ogc"
matchCase="true">
<p1:expression xmlns:p2="http://www.w3.org/2001/XMLSchema"
xsi:type="p2:string">coll:isActive</p1:expression>
<p1:expression xsi:type="coll:Boolean">true</p1:expression>
</PropertyIsEqualTo>
</p1:Filter>
</wfs:Query>
</wfs:GetFeature>
So the serialization method from Expression is obviously used. What am i
doing wrong ? Did i miss something ?
Jan
Boris Kolpackov schrieb:
> Hi Jan,
>
> Jan Klimke <jan.klimke at hpi.uni-potsdam.de> writes:
>
>
>> i tried to create an PropertyIsEqualTo element which is defined as follows:
>>
>> <xsd:element name="PropertyIsEqualTo"
>> type="ogc:BinaryComparisonOpType"
>> substitutionGroup="ogc:comparisonOps"/>
>>
>> [...]
>>
>> As you can see, the generated element is not the desired one but
>> "PropertyIsGreaterThanOrEqualTo".
>>
>> This element is defined like the PropertyIsEqualTo element:
>>
>> <xsd:element name="PropertyIsGreaterThanOrEqualTo"
>> type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
>>
>> Because they are both of the same type no other class as
>> ogc:BinaryComparisonOpType is generated.
>>
>
> It looks like this schema is using element names as some sort of
> identifiers even though they are all of the same type. This does
> not work very well with XSD's automatic handling of substitution
> groups since the generated code uses the first element name that
> matches the type. I see two ways how you can resolve this:
>
> 1. You can change the schema to an equivalent one but which assigns
> different types to different operation elements. This schema will
> be equivalent to the original in the sense that it will define
> the same XML vocabulary:
>
> <xsd:complexType name="IsEqualToType">
> <xsd:complexContent>
> <xsd:extension base="ogc:BinaryComparisonOpType"/>
> </xsd:complexContent>
> </xsd:complexType>
>
> <xsd:element name="PropertyIsEqualTo"
> type="ogc:IsEqualToType"
> substitutionGroup="ogc:comparisonOps"/>
>
> <xsd:complexType name="IsGreaterThanOrEqualToType">
> <xsd:complexContent>
> <xsd:extension base="ogc:BinaryComparisonOpType"/>
> </xsd:complexContent>
> </xsd:complexType>
>
> <xsd:element name="PropertyIsGreaterThanOrEqualTo"
> type="ogc:IsGreaterThanOrEqualToType"
> substitutionGroup="ogc:comparisonOps"/>
>
> And so on for all the elements that substitute comparisonOps and are
> of the BinaryComparisonOpType type.
>
> 2. The second method is quite a bit more involved but does not require
> any schema modifications. With this method you will need to customize
> all the types that contain the comparisonOps element (e.g., FilterType).
> Your customization will need to do two things:
>
> a) Add a mechanism for specifying which element name should be used.
> This can be a modifier function that passes element name as a
> string.
>
> b) Customize the serialization operator to change the name of the
> DOM element.
>
>
> For more information on type customization, see the C++/Tree
> Mapping Customization Guide:
>
> http://wiki.codesynthesis.com/Tree/Customization_guide
>
> There is also a bunch of examples in the examples/cxx/tree/custom/
> directory with the most relevant to your case being 'wildcard'.
>
> Here is an outline of the FilterType implementation. In your case
> you don't need to customize parsing so we just call the base
> implementation (or you can change it to extract the operation
> name from DOM):
>
> class FilterType: public FilterTypeBase
> {
> public:
> void
> comparisonOpName (const std::string& name)
> {
> comparisonOpName_ = name;
> }
>
> const std::string&
> comparisonOpName () const
> {
> return comparisonOpName_;
> }
>
> // Parsing constructor. Just call our base.
> //
> FilterType (const xercesc::DOMElement& e,
> xml_schema::flags = 0,
> xml_schema::container* = 0)
> : data_base (e, f, c)
> {
> }
>
> ...
>
> private:
> std::string comparisonOpName_;
> };
>
> // Serialization operator.
> //
> void
> operator<< (xercesc::DOMElement&, const FilterType& f)
> {
> // Use our base to serialize data and id.
> //
> const FilterTypeBase& fb (f);
> e << fb;
>
> if (f.comparisonOps ().present ())
> {
> // Change the name of the child element of 'e' to the one
> // returned by f.comparisonOpName (). Use the renameNode()
> // function on DOMDocument.
> }
> }
>
> When you use this type in your code you will need to set the
> actual name of the comparisonOps element manually.
>
>
>
>> And also the instance of PropertyNameType and LiteralType where not
>> serialized as the elements i wanted.
>>
>
> It is hard to answer this without knowing what you actually wanted ;-).
>
>
>
>> The other issue i found was assigning boolean values as a LiteralType
>> instance. The does not work because xml_schema::boolean does not
>> derrive from xml_schema::type.
>>
>
> That's right. Types that are mapped to fundamental C++ types cannot
> be used for dynamic typing. What you can do is add a type that derives
> from the boolean XML Schema type:
>
> <xsd:simpleType name="Boolean">
> <xsd:restriction base="xsd:boolean"/>
> </xsd:simpleType>
>
> Then you can use this type since it will be derived from xml_schema::type.
>
> Boris
>
More information about the xsd-users
mailing list