99
votes

I am using the XML Data Binding Wizard in Delphi XE2. The schema has required tags of this type:

<xs:element name="MyReport" type="MyReportType" />
<xs:complexType name="MyReportType">
  <xs:all>
    <xs:element name="Header" type="HeaderType" />
    <xs:element name="Values" type="ValuesType" />
    <xs:element name="Events" type="EventsType" />
  </xs:all>
</xs:complexType>

The problem is that if I don't add any elements to e.g. the Values-group, there will be no <Values>-tag, and the XML-file will fail validation against the XSD. This probably would not be a problem if the interface was providing a method for "adding" the Values-tag.

Is there a standard way of handling this, or am I using the generated code in-correctly?

Put simply, is there any way, work-around or otherwise, using the code from the Data Binding Wizard, to produce the following XML (which is what is needed to validate using the above schema when there are no child nodes), given HeaderType, ValuesType and EventsType are of complexType:

<MyReport>
  <Header />
  <Values />
  <Events />
</MyReport> 

(I know there are other similar issues, like the code generated by <xs:sequence> not enforcing the correct order in the final XML-file, but at least for that one, there's a work-around by simply inserting the children in the right order. I still think it would be nice if Embarcadero would provide a complete interface, which takes more of these features into account.)

1
You've already discovered the root of the issue when mentioned ordering. The generated class is a dumb wrapper around the XML object model; it will only exists when asked to. With string types this is easy enough (just add an empty string) but for complex types I'm not sure if nil will work.Leonardo Herrera
This is actually not quite true. The code for TXMLValuesType.AfterConstruction reads RegisterChildNode('Value', TXMLValueType); FValue := CreateCollection(TXMLValueTypeList, IXMLValueType, 'Value') as IXMLValueTypeList; so the collection of Value-items (under the parent Values-tag) exists, which is what makes it so hard to create the empty Values-tag. The empty Value-list will effectively stop you from forcing SaveToFile to produce the <Values />-tagRandomeister
@Randomeister - Try the minOccurs="1" attribute in your XSD: <xs:all maxOccurs="1">. Also, try using <xs:sequence> instead of <xs:all> . I have worked a good deal with the binding wizard (in Delphi XE) and have not encountered any problems - but you do have to make sure that you declare your types and attributes correctly so the wizard understands order and mandatory values.Vector

1 Answers

1
votes

Not sure to understand but maybe what you are looking for is : use="optional"

<xs:element name="MyReport" type="MyReportType" />
<xs:complexType name="MyReportType">
  <xs:all>
    <xs:element name="Header" type="HeaderType" use="optional" />
    <xs:element name="Values" type="ValuesType" use="optional" />
    <xs:element name="Events" type="EventsType" use="optional" />
  </xs:all>
</xs:complexType>

Tell me if it's okay.