[xsde-users] Cannot get the value

Boris Kolpackov boris at codesynthesis.com
Fri Jul 4 10:13:54 EDT 2008


Hi Keith,

Keith Oppenheim <KOppenheim at nextpointnetworks.com> writes:

> The schema fragment attached by Khuong comes directly from the NETCONF
> schema defined in RFC 4741.  The schema defines a <source> element
> that's nested inside of a <get-config> element.  The <source> element is
> of type="getConfigSourceType":
> 
> <xs:complexType name="getConfigSourceType">
>      <xs:choice>
>          <xs:element ref="config-name"/>
>          <xs:element name="url" type="configURIType"/>
>      </xs:choice>
> </xs:complexType>
> 
> The schema is structured to give the user flexibility in defining the
> element nested within <source>.  The user can nest one of <running/>,
> <candidate/>, or <startup/> elements within <source>.  Alternatively,
> via the substitution group mechanism, the user can nest any user-defined
> element as long as it derives from configNameType and uses <config-name>
> as the head of its substitution group. 

Did I understand this correctly: the running, candidate, and startup
elements do not carry any information other than just their names since
they are of the same empty configNameType type? In other words they
act as tags or type ids of some sort?

If that's the case then the trouble with using XSD/e in this kind of
situation is that the generated code handles XML Schema polymorphism
(xsi:type and substitution groups) transparently. It figures out the
type of parser that should be used and calls it. This is normally
exactly what you want since in most cases the substituting elements
have different types. But in this case the name of the element is
the only information.

I can see two ways to handle this. First is to modify the schema
to assign different (but still empty) types to running, candidate,
and startup:

<xs:complexType name="startupType">
  <complexContent>
    <extension base="configNameType"/>
  </complexContent>
</xs:complexType>

<xs:element name="startup" type="startupType" 
            substitutionGroup="config-name"/>

<xs:complexType name="candidateType">
  <complexContent>
    <extension base="configNameType"/>
  </complexContent>
</xs:complexType>

<xs:element name="candidate" type="candidateType" 
            substitutionGroup="config-name"/>

<xs:complexType name="runningType">
  <complexContent>
    <extension base="configNameType"/>
  </complexContent>
</xs:complexType>

<xs:element name="running" type="runningType" 
            substitutionGroup="config-name"/>

The resulting schema will be semantically equivalent to the original
but now you can determine which element was specified based on the
parser that has been called.

The second approach does not require schema modification and involves
overriding low-level _start_element() function to detect the element
name:

class getConfigSourceType_pimpl: getConfigSourceType_pskel
{
public:
  virtual void
  _start_element (const xml_schema::ro_string& ns,
                  const xml_schema::ro_string& name
                  const char* type)
  {
     if (ns == "...")
     {
       if (name == "running")
       {
         // running element
       }
       else if (name == "candidate")
       {
         // candidate element
       }
       else if (name == "startup")
       { 
         // startup element
       }
     }

     // Always call the base _start_element().
     //
     getConfigSourceType_pskel::_start_element (ns, name, type);
  }

  ...
};

Boris



More information about the xsde-users mailing list