Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 


In this blog, I will briefly explain the generation of an XSD to define the consumer interface structure for EC Compound Employee API.

 

Generation of an interface structure file for EC Compound Employee API

 

Employee Central's Compound Employee API supports now the generation of a consumer interface structure file by returning such an XSD as query response.

 

To generate an XSD query parameter resultOption with value xsd needs to be passed when calling the Compound Employee API via the query request. The result for such a query is an XSD that matches the query response structure for the requested select items and the given query mode in the query request. Special about the XSD is, it corresponds to the succession data model configuration of the given company that is used in the login operation.

 

How-to generate a schema file

 

  1. Trigger a query for Compound Employee API using XSD mode in your middleware or any other XML tool

    • Set resultOptions parameter to value XSD

    • Use xsdOptions parameter value to define the XSD according to your requirements (see explanations in "XSD generation options")

    • Examples for the query can be found at the end of this blog.



  2. Copy the XML response as described in "XSD query response handling" on this page

  3. Use any XML editor  and past copied parts in a new page

  4. Save result in XML editor as schema file

  5. Upload schema file in middleware to define a new Compond Employee API interface definition


 

XSD generation options

 

This new feature also provides the freedom to influence the structure dependent on the consumer needs. Query parameter xsdOptions can be utilized for this. It supports certain options, which have the following effects on the structure of the query response:

 

  • If no xsdOptions query parameter value is passed, the generated XSD contains all fields included in Compound Employee APIs static set of fields and all additional fields that have the visibility edit, view, or both in the Succession Data Models. For personal global information the XSD contains an element for each configured country. For MDF object-based segments the XSD contains all relevant fields defined in the corresponding object model.



  • Passing value returnAllFields will return the superset of all fields supported by Compound Employee API. The generated XSD contains all fields included in its static set of fields and all additional and configurable fields of any of the Succession Data Models, independent of their visibility. For personal global information the generated XSD contains all supported countries and not only the configured ones. This parameter doesn't have an impact on MDF object based segments.



  • Passing value returnAllSegments will return all segments supported by Compound Employee API including all MDF objects registered for extensibility. Segments passed as select items do not have an impact on the generated XSD.


 

  • Passing value useWeakTypes leads to a generated XSD in which data type String is used for all numeric typed fields (Long or Double) in the XSD (see below).


Special handling for numeric typed fields using xsdOptions parameter value useWeakTypes


 

Numeric typed fields can be handled considering the modeling of the field in the Succession Data Models, which depends on the parameter value that is passed via the query request. If a numeric field is defined with a reference to a picklist, foundation object, or generic object, the data type used in the generated XSD needs to be String instead of Long or Double. This behavior is required because the Compound Employee API exposes the external code for these referenced object. Keeping the original numeric typing may cause validation issue on consumer side as external codes also may contain characters.

 

The tables below give an overview about the XSD results for fields with different data types, data model configuration, and xsdOptions used. In these examples, ExtRef means "external reference". It indicates that the field has a reference to a picklist, foundation object, or generic object modeled in the Succession Data Model.

 



 

Table above shows the result of XSD generation behavior for country independent select items such as personal information, email, phone or select items that have a global model such as employment information, job information, or compensation information.

 

 

 



 

Table above shows the XSD generation behavior for country dependent select items such as personal global information or address information.

 

 

XSD query response handling

 

The query response for the XSD generation contains more information than needed for the consumer interface structure. From the query response the information needs to be taken as shown in the example below marked in the pink color to define the schema file.

<?xml version="1.0"?>


<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">


  <S:Body>


      <queryResponse xmlns="urn:sfobject.sfapi.successfactors.com"


                                xmlns:ns2="urn:fault.sfapi.successfactors.com">


        <result>


            <sfobject>


              <id>xsd</id>


              <type>CompoundEmployee</type>


              <xsd><![CDATA[


 

                                      <?xml version="1.0" encoding="UTF-8"?>


                                        <xs:schema xmlns="urn:sfobject.sfapi.successfactors.com"


                                        xmlns:xs="http://www.w3.org/2001/XMLSchema"


                                        targetNamespace="urn:sfobject.sfapi.successfactors.com"


                                        elementFormDefault="qualified">


                                        ...


                                        </xs:schema> 


                                                                 ]]>


              </xsd>


            </sfobject>


            <numResults>1</numResults>


            <hasMore>false</hasMore>


            <querySessionId>0ee36b8a-0e21-4e47-942d-f8ef4e6431a1</querySessionId>


        </result>


      </queryResponse>


  </S:Body>


</S:Envelope>


 

 

 

Examples for a request and response considering only person and address

Request :

    <urn:query>
<urn:queryString>
SELECT address_information ,person FROM CompoundEmployee
</urn:queryString>
<urn:param>
<urn:name>resultOptions</urn:name>
<urn:value>XSD</urn:value>
</urn:param>
</urn:query>

Response after modification (see section XSD query response handling😞

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="urn:sfobject.sfapi.successfactors.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:sfobject.sfapi.successfactors.com" elementFormDefault="qualified">
<xs:element name="queryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="result" type="QueryResult"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CompoundEmployee" type="SFObject"/>
<xs:complexType name="QueryResult">
<xs:sequence>
<xs:element name="sfobject" type="SFObject" maxOccurs="unbounded"/>
<xs:element name="numResults" type="xs:short"/>
<xs:element name="hasMore" type="xs:boolean"/>
<xs:element name="querySessionId" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SFObject">
<xs:sequence>
<xs:element name="id" type="xs:string"/>
<xs:element name="type" type="xs:string"/>
<xs:element name="person" type="personType" minOccurs="0"/>
<xs:element name="log" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="log_item" type="logItemType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="execution_timestamp" type="formattedDateTime"/>
<xs:element name="version_id" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="logItemType">
<xs:sequence>
<xs:element name="per_person_uuid" type="xs:string" minOccurs="0"/>
<xs:element name="person_id" type="xs:string" minOccurs="0"/>
<xs:element name="person_id_external" type="xs:string" minOccurs="0"/>
<xs:element name="node_name" type="xs:Name" minOccurs="0"/>
<xs:element name="field_name" type="xs:Name" minOccurs="0"/>
<xs:element name="xpath" type="xs:string" minOccurs="0"/>
<xs:element name="severity" type="xs:string" minOccurs="0"/>
<xs:element name="message_text" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="formattedDate">
<xs:annotation>
<xs:documentation>Date with format yyyy-MM-dd</xs:documentation>
<xs:appinfo>
<dataFormat dataType="datetime" format="yyyy-MM-dd"/>
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:date"/>
</xs:simpleType>
<xs:simpleType name="formattedDateTime">
<xs:annotation>
<xs:documentation>Timestamp with format yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</xs:documentation>
<xs:appinfo>
<dataFormat dataType="datetime" format="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"/>
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:dateTime"/>
</xs:simpleType>
<xs:complexType name="personType">
<xs:sequence>
<xs:element name="birth_name" type="xs:string" minOccurs="0"/>
<xs:element name="country_of_birth" type="xs:string" minOccurs="0"/>
<xs:element name="created_by" type="xs:string" minOccurs="0"/>
<xs:element name="created_on_timestamp" type="formattedDateTime" minOccurs="0"/>
<xs:element name="custom_date1" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date10" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date2" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date3" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date4" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date5" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date6" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date7" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date8" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date9" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_double1" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double10" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double11" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double12" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double13" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double14" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double15" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double16" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double17" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double18" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double19" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double2" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double20" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double3" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double4" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double5" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double6" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double7" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double8" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double9" type="xs:double" minOccurs="0"/>
<xs:element name="custom_long1" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long10" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long11" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long12" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long13" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long14" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long15" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long16" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long17" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long18" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long19" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long2" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long20" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long3" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long4" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long5" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long6" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long7" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long8" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long9" type="xs:long" minOccurs="0"/>
<xs:element name="custom_string1" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string10" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string11" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string12" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string13" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string14" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string15" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string16" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string17" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string18" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string19" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string2" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string20" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string3" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string4" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string5" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string6" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string7" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string8" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string9" type="xs:string" minOccurs="0"/>
<xs:element name="date_of_birth" type="formattedDate" minOccurs="0"/>
<xs:element name="date_of_death" type="formattedDate" minOccurs="0"/>
<xs:element name="last_modified_by" type="xs:string" minOccurs="0"/>
<xs:element name="last_modified_on" type="formattedDateTime" minOccurs="0"/>
<xs:element name="logon_user_id" type="xs:string" minOccurs="0"/>
<xs:element name="logon_user_is_active" type="xs:string" minOccurs="0"/>
<xs:element name="logon_user_name" type="xs:string" minOccurs="0"/>
<xs:element name="per_person_uuid" type="xs:string" minOccurs="0"/>
<xs:element name="person_id" type="xs:string" minOccurs="0"/>
<xs:element name="person_id_external" type="xs:string" minOccurs="0"/>
<xs:element name="place_of_birth" type="xs:string" minOccurs="0"/>
<xs:element name="region_of_birth" type="xs:string" minOccurs="0"/>
<xs:element name="address_information" type="addressInformationType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addressInformationType">
<xs:sequence>
<xs:element name="address1" type="xs:string" minOccurs="0"/>
<xs:element name="address10" type="xs:string" minOccurs="0"/>
<xs:element name="address10_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address11" type="xs:string" minOccurs="0"/>
<xs:element name="address11_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address12" type="xs:string" minOccurs="0"/>
<xs:element name="address12_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address13" type="xs:string" minOccurs="0"/>
<xs:element name="address13_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address14" type="xs:string" minOccurs="0"/>
<xs:element name="address15" type="xs:string" minOccurs="0"/>
<xs:element name="address16" type="xs:string" minOccurs="0"/>
<xs:element name="address17" type="xs:string" minOccurs="0"/>
<xs:element name="address18" type="xs:string" minOccurs="0"/>
<xs:element name="address19" type="xs:string" minOccurs="0"/>
<xs:element name="address1_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address1_alt2" type="xs:string" minOccurs="0"/>
<xs:element name="address2" type="xs:string" minOccurs="0"/>
<xs:element name="address20" type="xs:string" minOccurs="0"/>
<xs:element name="address2_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address2_alt2" type="xs:string" minOccurs="0"/>
<xs:element name="address3" type="xs:string" minOccurs="0"/>
<xs:element name="address3_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address3_alt2" type="xs:string" minOccurs="0"/>
<xs:element name="address4" type="xs:string" minOccurs="0"/>
<xs:element name="address4_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address5" type="xs:string" minOccurs="0"/>
<xs:element name="address5_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address6" type="xs:string" minOccurs="0"/>
<xs:element name="address6_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address7" type="xs:string" minOccurs="0"/>
<xs:element name="address7_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address8" type="xs:string" minOccurs="0"/>
<xs:element name="address8_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address9" type="xs:string" minOccurs="0"/>
<xs:element name="address9_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="address_type" type="xs:string" minOccurs="0"/>
<xs:element name="city" type="xs:string" minOccurs="0"/>
<xs:element name="city_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="country" type="xs:string" minOccurs="0"/>
<xs:element name="country_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="county" type="xs:string" minOccurs="0"/>
<xs:element name="county_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="created_by" type="xs:string" minOccurs="0"/>
<xs:element name="created_on_timestamp" type="formattedDateTime" minOccurs="0"/>
<xs:element name="custom_date1" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date10" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date2" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date3" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date4" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date5" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date6" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date7" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date8" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_date9" type="formattedDate" minOccurs="0"/>
<xs:element name="custom_double1" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double10" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double11" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double12" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double13" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double14" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double15" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double16" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double17" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double18" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double19" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double2" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double20" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double3" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double4" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double5" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double6" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double7" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double8" type="xs:double" minOccurs="0"/>
<xs:element name="custom_double9" type="xs:double" minOccurs="0"/>
<xs:element name="custom_long1" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long10" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long11" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long12" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long13" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long14" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long15" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long16" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long17" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long18" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long19" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long2" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long20" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long3" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long4" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long5" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long6" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long7" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long8" type="xs:long" minOccurs="0"/>
<xs:element name="custom_long9" type="xs:long" minOccurs="0"/>
<xs:element name="custom_string1" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string10" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string11" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string12" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string13" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string14" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string15" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string16" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string17" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string18" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string19" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string2" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string20" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string3" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string4" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string5" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string6" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string7" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string8" type="xs:string" minOccurs="0"/>
<xs:element name="custom_string9" type="xs:string" minOccurs="0"/>
<xs:element name="emp_users_sys_id" type="xs:string" minOccurs="0"/>
<xs:element name="end_date" type="formattedDate" minOccurs="0"/>
<xs:element name="formatted_address_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="is_global_model_address" type="xs:boolean" minOccurs="0"/>
<xs:element name="last_modified_by" type="xs:string" minOccurs="0"/>
<xs:element name="last_modified_on" type="formattedDateTime" minOccurs="0"/>
<xs:element name="notes" type="xs:string" minOccurs="0"/>
<xs:element name="province" type="xs:string" minOccurs="0"/>
<xs:element name="start_date" type="formattedDate" minOccurs="0"/>
<xs:element name="state" type="xs:string" minOccurs="0"/>
<xs:element name="state_alt1" type="xs:string" minOccurs="0"/>
<xs:element name="zip_code" type="xs:string" minOccurs="0"/>
<xs:element name="zip_code_alt1" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>

 

 

Additional information

 

You can find further info under in http://help.sap.com/hr_api/ or about Compound Employee API: http://service.sap.com/~sapidb/002007974700000283532014E

 

Looking forward to your questions and feedback in the comments section.

5 Comments