Using a Mendix oData service from a Mendix app

6
Hi,   I am trying to comsume an oData service (published from a Mendix app) and get an xml result so I can use an import mapping to process the result.   When I write the Rest call response to a string, I get this xml string: <?xml version="1.0" encoding="UTF-8"?> <feed xml:base="http://ga:8080/odata/Published_OData_service/" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns="http://www.w3.org/2005/Atom">     <id>http://ga:8080/odata/Published_OData_service/Garantie</id>     <title>Garantie</title>     <updated>2017-06-14T13:06:32.053Z</updated>     <link href="Garantie" rel="self" title="Garantie"/>     <entry>         <id>http://ga:8080/odata/Published_OData_service/Garantie(16044073672509093)</id>         <category term="DefaultNamespace.Garantie" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>         <title/>         <updated>1970-01-01T00:00:00.000Z</updated>         <content type="application/xml">             <m:properties>                 <d:ID m:type="Edm.Int64">16044073672509093</d:ID>                 <d:Garantienummer m:type="Edm.Int64">4</d:Garantienummer>                 <d:Status m:type="Edm.String">Actief</d:Status>                 <d:TotaalLeningbedrag m:type="Edm.Decimal">2800000</d:TotaalLeningbedrag>                 <d:GegarandeerdBedrag m:type="Edm.Decimal">0</d:GegarandeerdBedrag>                 <d:Begindatum m:type="Edm.DateTimeOffset">2016-11-18T00:00:00.000Z</d:Begindatum>                 <d:Melddatum m:type="Edm.DateTimeOffset">2016-11-21T09:51:36.234Z</d:Melddatum>                 <d:Einddatum m:type="Edm.DateTimeOffset" m:null="true"/>                 <d:_HeeftWaarschuwing m:type="Edm.Boolean">false</d:_HeeftWaarschuwing>                 <d:TotaalBedragAflossing m:type="Edm.Decimal">0</d:TotaalBedragAflossing>                 <d:AnnuitaireDaling m:type="Edm.Decimal">0</d:AnnuitaireDaling>                 <d:OpgebouwdeWaarde m:type="Edm.Decimal">0</d:OpgebouwdeWaarde>                 <d:GeborgdBedrag m:type="Edm.Decimal">0</d:GeborgdBedrag>             </m:properties>         </content>     </entry> </feed>   Now in order to make the mapping, I was trying to create an XSD from this XML using free online "XML to XSD converter", but I have tried five different converters and they all produce different XSDs which all give errors when trying to import them into the modeler. The XSD I have had the best succes with is: <?xml version="1.0" encoding="utf-8"?> <xs:schema id="NewDataSet" targetNamespace="http://www.w3.org/2005/Atom" xmlns:mstns="http://www.w3.org/2005/Atom" xmlns="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:app2="http://schemas.microsoft.com/ado/2007/08/dataservices">     <xs:import namespace="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" schemaLocation="636331195910115922_odata.xml_app1.xsd" />     <xs:import namespace="http://schemas.microsoft.com/ado/2007/08/dataservices" schemaLocation="636331195910115922_odata.xml_app2.xsd" />     <xs:element name="feed">         <xs:complexType>             <xs:sequence>                 <xs:element name="id" type="xs:string" minOccurs="0" />                 <xs:element name="title" type="xs:string" minOccurs="0" />                 <xs:element name="updated" type="xs:string" minOccurs="0" />                 <xs:element name="link" minOccurs="0" maxOccurs="unbounded">                     <xs:complexType>                         <xs:attribute name="href" form="unqualified" type="xs:string" />                         <xs:attribute name="rel" form="unqualified" type="xs:string" />                         <xs:attribute name="title" form="unqualified" type="xs:string" />                     </xs:complexType>                 </xs:element>                 <xs:element name="entry" minOccurs="0" maxOccurs="unbounded">                     <xs:complexType>                         <xs:sequence>                             <xs:element name="id" type="xs:string" minOccurs="0" />                             <xs:element name="title" type="xs:string" minOccurs="0" />                             <xs:element name="updated" type="xs:string" minOccurs="0" />                             <xs:element name="category" minOccurs="0" maxOccurs="unbounded">                                 <xs:complexType>                                     <xs:attribute name="term" form="unqualified" type="xs:string" />                                     <xs:attribute name="scheme" form="unqualified" type="xs:string" />                                 </xs:complexType>                             </xs:element>                             <xs:element name="content" minOccurs="0" maxOccurs="unbounded">                                 <xs:complexType>                                     <xs:sequence>                                         <xs:element ref="app1:properties" />                                     </xs:sequence>                                     <xs:attribute name="type" form="unqualified" type="xs:string" />                                 </xs:complexType>                             </xs:element>                         </xs:sequence>                     </xs:complexType>                 </xs:element>             </xs:sequence>         </xs:complexType>     </xs:element>     <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">         <xs:complexType>             <xs:choice minOccurs="0" maxOccurs="unbounded">                 <xs:element ref="feed" />             </xs:choice>         </xs:complexType>     </xs:element> </xs:schema>   Which I changed a bit because the "properties" element wasn't declared (and its simple attributes are nowhere to be found). So I created this XSD: <?xml version="1.0" encoding="utf-8"?> <xs:schema id="NewDataSet" targetNamespace="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns="http://www.w3.org/2005/Atom">     <xs:element name="feed">         <xs:complexType>             <xs:sequence>                 <xs:element name="id" type="xs:string" minOccurs="0" />                 <xs:element name="title" type="xs:string" minOccurs="0" />                 <xs:element name="updated" type="xs:string" minOccurs="0" />                 <xs:element name="link" minOccurs="0" maxOccurs="unbounded">                     <xs:complexType>                         <xs:attribute name="href" form="unqualified" type="xs:string" />                         <xs:attribute name="rel" form="unqualified" type="xs:string" />                         <xs:attribute name="title" form="unqualified" type="xs:string" />                     </xs:complexType>                 </xs:element>                 <xs:element name="entry" minOccurs="0" maxOccurs="unbounded">                     <xs:complexType>                         <xs:sequence>                             <xs:element name="id" type="xs:string" minOccurs="0" />                             <xs:element name="title" type="xs:string" minOccurs="0" />                             <xs:element name="updated" type="xs:string" minOccurs="0" />                             <xs:element name="category" minOccurs="0" maxOccurs="unbounded">                                 <xs:complexType>                                     <xs:attribute name="term" form="unqualified" type="xs:string" />                                     <xs:attribute name="scheme" form="unqualified" type="xs:string" />                                 </xs:complexType>                             </xs:element>                             <xs:element name="content" minOccurs="0" maxOccurs="unbounded">                                 <xs:complexType>                                     <xs:sequence>                                          <xs:element name="properties">                                             <xs:complexType>                                                 <xs:sequence>                                                     <xs:element name="ID" type="xs:int"/>                                                     <xs:element name="Garantienummer" type="xs:int"/>                                                     <xs:element name="Status" type="xs:string"/>                                                     <xs:element name="TotaalLeningbedrag" type="xs:int"/>                                                     <xs:element name="GegarandeerdBedrag" type="xs:int"/>                                                     <xs:element name="Begindatum" type="xs:string"/>                                                     <xs:element name="Melddatum" type="xs:string"/>                                                     <xs:element name="Einddatum" type="xs:string"/>                                                     <xs:element name="_HeeftWaarschuwing" type="xs:string"/>                                                     <xs:element name="TotaalBedragAflossing" type="xs:int"/>                                                     <xs:element name="AnnuitaireDaling" type="xs:int"/>                                                     <xs:element name="OpgebouwdeWaarde" type="xs:int"/>                                                     <xs:element name="GeborgdBedrag" type="xs:int"/>                                                 </xs:sequence>                                             </xs:complexType>                                         </xs:element>                                     </xs:sequence>                                 </xs:complexType>                             </xs:element>                         </xs:sequence>                     </xs:complexType>                 </xs:element>             </xs:sequence>         </xs:complexType>     </xs:element> </xs:schema>   Which imports perfectly and even leads to a very convincing import mapping:   Only problem: The properties element is always empty, even though in the xml, you can clearly see it has content.   Can someone help me fabricate a good XSD with which I can consume my oData service.
asked
2 answers
6

This has been on my backlog for writing a blog post about. I'll try to explain how to create xsd's for an oData feed.

We are going to create 3 xsd's, I called them m.xsd, odataFeed.xsd and d.xsd  (of course you can give them any name, but my examples below refer to each other by name) in the same folder on disk. You import it into the modeler by importing the odataFeed.xsd. The first two XSDs are the same for any oData definition you like to use. I'll show them below:


m.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
    <xsd:import schemaLocation="d.xsd" namespace="http://schemas.microsoft.com/ado/2007/08/dataservices" />
      <xsd:complexType name="content">
        <xsd:sequence>
          <xsd:element name="properties" type="d:properties"/>  
        </xsd:sequence>
         <xsd:attribute name="type" type="xsd:string" />
      </xsd:complexType>
</xsd:schema>

 

odatafeed.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" targetNamespace="http://www.w3.org/2005/Atom">
  <xsd:import schemaLocation="m.xsd" namespace="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" />
  <xsd:element name="feed">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="id" type="xsd:string" />
        <xsd:element name="title" type="xsd:string" />
        <xsd:element name="updated" type="xsd:dateTime" />
        <xsd:element name="link">
          <xsd:complexType>
            <xsd:attribute name="href" type="xsd:string" />
            <xsd:attribute name="rel" type="xsd:string" />
            <xsd:attribute name="title" type="xsd:string" />
          </xsd:complexType>
        </xsd:element>
        <xsd:element name="entry" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="id" type="xsd:string" />
              <xsd:element name="category">
                <xsd:complexType>
                  <xsd:attribute name="term" type="xsd:string" />
                  <xsd:attribute name="scheme" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="title" type="xsd:string" />
              <xsd:element name="updated" type="xsd:dateTime" />
              <xsd:element name="content" type="m:content"/>
              </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
      <xsd:attribute name="base" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

 

The d.xsd finally depends on the actual structure of the data. Based on the properties in your feed I made the following d.xsd for your example:

d.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://schemas.microsoft.com/ado/2007/08/dataservices">
      <xsd:complexType name="properties">
        <xsd:sequence>
          <xsd:element name="ID" type="xsd:long"/>  
          <xsd:element name="Garantienummer" type="xsd:long"/>           
          <xsd:element name="Status" type="xsd:string"/> 
          <xsd:element name="TotaalLeningbedrag" type="xsd:decimal"/>
          <xsd:element name="GegarandeerdBedrag" type="xsd:decimal"/>
          <xsd:element name="Begindatum" type="xsd:dateTime"/>
          <xsd:element name="Melddatum" type="xsd:dateTime"/>
          <xsd:element name="Einddatum" type="xsd:dateTime"/>
          <xsd:element name="_HeeftWaarschuwing" type="xsd:boolean"/>
          <xsd:element name="TotaalBedragAflossing" type="xsd:decimal"/>
          <xsd:element name="AnnuitaireDaling" type="xsd:decimal"/>
          <xsd:element name="OpgebouwdeWaarde" type="xsd:decimal"/>
          <xsd:element name="GeborgdBedrag" type="xsd:decimal"/>          
        </xsd:sequence>
      </xsd:complexType>      
</xsd:schema>

 

I tried this all out with a mapping on the input you provide in your original post and it works. (So to be clear. Save all these XSDs in the same directory and make an XML schema document in the modeler based on the odataFeed.xsd).

 

Good luck!

answered
0

This seems to be quite complex and error prone. If you need a fast data transfer consider retrieving data with OQL (in java) and transform the data to json or another compact data format and send it to the other app.

answered