Skip to main content

Using Datasets in SOAP Messages

This chapter discusses %XML.DataSet, which is an XML-enabled dataset that you can use in SOAP messages when both the web service and client are based on Caché or when one side uses .NET. Other SOAP vendors do not support datasets.

This chapter provides the details on the following:

About Datasets

A dataset is an XML-format result set defined by Microsoft (and used for .NET) and also supported in Caché. If both the web service and client are based on Caché or when one side uses .NET, you can use datasets as input to or output from a web method. Other SOAP technologies do not understand this format.

When you work with web services or clients in Caché, you use %XML.DataSetOpens in a new tab (or a custom subclass) to represent a dataset. %XML.DataSetOpens in a new tab is an XML-enabled subclass of the standard %ResultSetOpens in a new tab class, and you use it in the same way you use that class. See “Using Dynamic SQL” in Using Caché SQL.

Note:

The %XML.DataSetOpens in a new tab class supports only a single table. That is, the query it uses can return only a single table.

The sample web service SOAP.DemoOpens in a new tab (in the SAMPLES namespace) demonstrates datasets in Caché. Specifically, the following web methods use datasets:

  • GetByName()

  • GetDataSetByName()

  • QueryByName()

To output results of a query so that a Java-based web client can work with it, use a %ListOfObjectsOpens in a new tab subclass; SOAP.DemoOpens in a new tab shows an example.

Defining a Typed Dataset

Any dataset uses a query that specifies the data to retrieve. If the query is known at compile time, the dataset is typed; otherwise it is untyped. Typed datasets are convenient in many cases; for example, in .NET, a typed dataset allows code completion in Microsoft Visual Studio.

To define a typed dataset, create a subclass of %XML.DataSetOpens in a new tab and specify the QUERYNAME and CLASSNAME parameters. Together, these parameters refer to a specific SQL query. When it generates the schema for the dataset, %XML.DataSetOpens in a new tab considers the class and property metadata such as any LogicalToXSD() methods in custom data types.

Note:

If you use %XML.DataSetOpens in a new tab as the return value for a method, the XML type for that value is DataSet. On the other hand, if you use a subclass of %XML.DataSetOpens in a new tab as the return value, the XML type for the value is the name of that subclass. This behavior is the same as that of other XML-enabled classes, and it affects the XML types that are described in the WSDL. See the chapter “Controlling the Projection to XML Types” in Projecting Objects to XML

Controlling the Dataset Format

By default, a dataset is written in Microsoft DiffGram format and is preceded by its XML schema. The following shows an example:

<SOAP-ENV:Body>
  <Get0Response xmlns="http://www.myapp.org">
    <Get0Result>
    <s:schema id="DefaultDataSet" xmlns="" 
    attributeFormDefault="qualified" 
    elementFormDefault="qualified"
    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
      <s:element name="DefaultDataSet" msdata:IsDataSet="true">
        <s:complexType>
          <s:choice maxOccurs="unbounded">
            <s:element name="GetPeople">
              <s:complexType>
                <s:sequence>
                  <s:element name="Name" type="s:string" minOccurs="0" />
                  <s:element name="DOB" type="s:date" minOccurs="0" />
                </s:sequence>
              </s:complexType>
            </s:element>
          </s:choice>
        </s:complexType>
      </s:element>
    </s:schema>

    <diffgr:diffgram 
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
    xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
      <DefaultDataSet xmlns="">
        <GetPeople diffgr:id="GetPeople1" msdata:rowOrder="0">
          <Name>Quine,Howard Z.</Name>
          <DOB>1965-11-29</DOB>
        </GetPeople>
...
      </DefaultDataSet>
    </diffgr:diffgram>
   </Get0Result>
 </Get0Response>  
</SOAP-ENV:Body>

The %XML.DataSetOpens in a new tab class provides the following options for controlling this format:

  • The DATAONLY parameter and the DiffGram property control whether the output is in DiffGram format. By default, the output is in DiffGram format, which is shown above. If you subclass %XML.DataSetOpens in a new tab and set DATAONLY equal to 1, or if you set the DiffGram equal to 0, the output is not in DiffGram format. The body of the XML dataset is as follows instead:

    <SOAP-ENV:Body>
      <Get0Response xmlns="http://www.myapp.org">
        <Get0Result>
          <GetPeople xmlns="">
            <Name>Quine,Howard Z.</Name>
            <DOB>1965-11-29</DOB>
          </GetPeople>
          <GetPeople xmlns="">
    ...
        </Get0Result>
      </Get0Response>  
    </SOAP-ENV:Body>
    

    In contrast to DiffGram format, notice that the schema is not output by default and that the output does not include the <diffgram> element.

  • The NeedSchema property controls whether the output includes the XML schema. If you are using DiffGram format, the default is to output the schema; if you are not using DiffGram format, the default is not to output the schema. To force output of the schema, set NeedSchema equal to 1, or to suppress output of the schema, set it equal to 0.

  • If you use DiffGram format, the WriteEmptyDiffgram property controls the contents of the <diffgram> element in the case when the dataset has no rows. By default (or if WriteEmptyDiffgram equals 0), the <diffgram> element contains an empty element as follows:

    ...
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
    xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
       <DefaultDataSet xmlns="">
       </DefaultDataSet>
    </diffgr:diffgram>
    ...
    

    In contrast, if WriteEmptyDiffgram equals 1, the <diffgram> element contains nothing:

    ...
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
    </diffgr:diffgram>
    ...
    

    This property has no effect if you are not using DiffGram format.

  • If you use DiffGram format, the DataSetName property controls the name of the element within the <diffgram> element. By default, this element is named <DefaultDataSet>, as you can see in the example above. This property has no effect if you are not using DiffGram format.

%XML.DataSetOpens in a new tab also provides the CaseSensitive property, which corresponds to the Microsoft dataset property of the same name. The default is false, for compatibility reasons.

Viewing the Dataset and Schema as XML

A dataset that extends %XML.DataSetOpens in a new tab has utility methods that you can use to generate XML. All of these methods write to the current device:

  • WriteXML() writes the dataset as XML, optionally preceded by the XML schema. This method has optional arguments to control the name of the top-level element, the use of namespaces, treatment of nulls, and so on. By default, this method considers the format of the dataset, as specified by the settings in the previous section. You can override that result by providing values for optional arguments that control whether the output is in DiffGram format and so on. For details, see the class documentation for %XML.DataSetOpens in a new tab.

  • XMLExport() writes the XML schema for the dataset, followed by the dataset as XML.

  • WriteSchema() writes just the XML schema for the dataset.

  • XMLSchema() writes the Microsoft proprietary XML representation of its dataset class.

For information on generating XML schemas from XML-enabled objects, see Using Caché XML Tools.

Effect on the WSDL

If a Caché web service uses %XML.DataSetOpens in a new tab as input or output to a web method, that affects the WSDL so that clients other than Caché and .NET have difficulty consuming the WSDL.

For a typed dataset, the WSDL includes the following elements (within the <types> section):

<s:element name="GetDataSetByNameResponse">
   <s:complexType>
      <s:sequence>
        <s:element name="GetDataSetByNameResult" type="s0:ByNameDataSet" /> 
      </s:sequence>
   </s:complexType>
</s:element>
<s:complexType name="ByNameDataSet">
   <s:sequence>
     <s:any namespace="http://tempuri.org/ByNameDataSet" /> 
   </s:sequence>
</s:complexType>

For an untyped dataset, the WSDL includes the following:

<s:element name="GetByNameResponse">
   <s:complexType>
      <s:sequence>
         <s:element name="GetByNameResult" type="s0:DataSet" /> 
      </s:sequence>
   </s:complexType>
</s:element>
<s:complexType name="DataSet">
   <s:sequence>
      <s:element ref="s:schema" /> 
   <s:any /> 
   </s:sequence>
</s:complexType>

In the latter case, if you attempt to generate a web client within a tool other than Caché or .NET, an error occurs because there is not enough information for that tool. For Metro, it is possible to load additional schema information before attempting to consume the WSDL. To do so, you can use a command-line tool called wsimport. This technique can provide enough information to generate the client.

In all cases, however, considerable work is necessary to write code so that the client can either interpret or generate messages in the appropriate form.

FeedbackOpens in a new tab