Victor
Victor

Reputation: 2546

How should I define my XSD to have dynamic types used as elements?

I am defining a XSD schema for the SOAP requests to be sent to a Web Service that accepts requests like these:

<generic.GenericObject.configureInstanceWithResult xmlns="xmlapi_1.0">
    [..]
    <configInfo>
        <lte.Cell>
            <actionMask>
                <bit>modify</bit>
            </actionMask>
            <spare1>1</spare1>
        </lte.Cell>
    </configInfo>
</generic.GenericObject.configureInstanceWithResult>
<generic.GenericObject.configureInstanceWithResult xmlns="xmlapi_1.0">
    [...]
    <configInfo>
        <lte.LteNeighboringCellRelation>
            <actionMask>
                <bit>modify</bit>
            </actionMask>
            <cellIndividualOffset>-1</cellIndividualOffset>
        </lte.LteNeighboringCellRelation>
    </configInfo>
</generic.GenericObject.configureInstanceWithResult>    

In order to achieve this result, I have tried with this schema definition:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="xmlapi_1.0" xmlns:tns="xmlapi_1.0" elementFormDefault="qualified">

<complexType name="Generic.GenericObject.configureInstanceWithResult">
    <sequence>
        [...]
        <element name="configInfo" type="tns:ConfigInfo" />
    </sequence>
</complexType>

<complexType name="ConfigInfo">
    <sequence>
        <element name="payload" type="anyType" />
    </sequence>
</complexType>

<complexType name="lte.Cell">
    <sequence>
        <element name="spare" type="string" />
    </sequence>
</complexType>

<complexType name="lte.LteNeighboringCellRelation">
    <sequence>
        <element name="qOffsetCell" type="string" />
        <element name="cellIndividualOffset" type="string" />
    </sequence>
</complexType>

<element name="generic.GenericObject.configureInstanceWithResult" type="tns:Generic.GenericObject.configureInstanceWithResult" />

But the result I get is this one:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<generic.GenericObject.configureInstanceWithResult xmlns="xmlapi_1.0">
    <configInfo>
        <payload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="lte.Cell">
            <spare>-1</spare>
        </payload>
    </configInfo>
</generic.GenericObject.configureInstanceWithResult>

Do you see any way in which I could have xsi:type="lte.Cell" as <lte.Cell> instead of <payload>?

Note: Using anyType in ConfigInfo is no good as <configInfo> gets removed and the request is no longer compliant.

Upvotes: 2

Views: 1537

Answers (2)

Victor
Victor

Reputation: 2546

As commented, I think that they best approach here is to have any as element in <ConfigInfo>:

<complexType name="ConfigInfo">
    <sequence>
       <any minOccurs="0" maxOccurs="1"/>
    </sequence>
</complexType>

This allows you to have any type of object marked with @XmlRootElementintroduced in your XML.

In this particular case where I had two classes defined in the schema as eligible for "payload", element declarations need to be introduced so they are marked correctly as @XmlRootElement:

<element name="lte.Cell" type="tns:Lte.Cell" />
<element name="lte.LteNeighboringCellRelation" type="tns:Lte.LteNeighboringCellRelation" />

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163635

Make payload into a global element declaration (preferably with abstract="true"), and create element declarations for lte.Cell and lte.LteNeighboringCellRelation that specify substitutionGroup="payload".

Upvotes: 0

Related Questions