How to use complex object elements in WSO2 DSS? - wso2

I'm new to WSO2 Data Services Server and I trying to figure out how to get complex element types working correctly with the web scraper. Using the interface I seem to be able to define the object, but I'm not sure how to use it once it is defined. Below is the Data Service XML...
<data name="ComplexTypeExample">
<description>A Description</description>
<config id="GetPrices">
<property name="web_harvest_config">./samples/resources/GetPrices.xml</property>
</config>
<query id="getSonyPrices" useConfig="GetPrices">
<scraperVariable>priceInfoSony</scraperVariable>
<result element="CameraInfo" rowName="Record">
<element column="Pic" name="Pic" xsdType="string"/>
<element column="Desc" name="Desc" xsdType="string"/>
<element name="Inventory" namespace="">
<element name="Item" namespace="">
<element column="Grade" name="Grade" xsdType="string"/>
<element column="Price" name="Price" xsdType="string"/>
</element>
</element>
</result>
</query>
<operation name="getSonyPricesOperation">
<description>Gets prices of KM/Sony cameras</description>
<call-query href="getSonyPrices"/>
</operation>
</data>
What I am trying to do is figure out how to get the Inventory element to be an array of Item types. Something like this...
<Record>
<Pic>Camera.jpg</Pic>
<Desc>A camera made by some company</Desc>
<Inventory>
<Item>
<Grade>Good</Grade>
<Price>$200</Price>
</Item>
<Item>
<Grade>Not So Good</Grade>
<Price>$100</Price>
</Item>
<Item>
<Grade>Broken</Grade>
<Price>$10</Price>
</Item>
</Inventory>
</Record>
Can anyone provide some hints as to where I'm going wrong?

Looks like you have done your complex element mapping correctly according to your result set .. Are you having trouble scraping the values? If so you have to provide us with the scraping configuration, and also you have to write the xslt file also according to your complex elements.
Please refer the following guide for web scraping

Related

Create Data Service with inner join

I'm trying to create a service with an inner join query but it returns this error:
org.postgresql.util.PSQLException: A result was returned when none was expected.
This is my service:
<data name="consultarPersona" transports="http https local">
<config enableOData="true" id="mi_datasource">
<property name="carbon_datasource_name">fuente_datos</property>
</config>
<query id="contactos_registrados" useConfig="mi_datasource">
<sql>select * from t_contacto inner join t_datos_contacto on t_contacto.id = t_datos_contacto.id</sql>
</query>
<operation name="obtenerDatosContactos">
<call-query href="contactos_registrados"/>
</operation>
</data>
You should specify which columns do you want to return and generate the response, the result is an service like this:
<data name="consultarPersona" transports="http https local">
<config enableOData="true" id="mi_datasource">
<property name="carbon_datasource_name">fuente_datos</property>
</config>
<query id="contactos_registrados" useConfig="mi_datasource">
<sql>select name, age from t_contacto inner join t_datos_contacto on t_contacto.id = t_datos_contacto.id</sql>
<result element="contactoCollection" rowName="contacto">
<element column="name" name="name" xsdType="xs:string"/>
<element column="age" name="age" xsdType="xs:string"/>
</result>
</query>
<operation name="obtenerDatosContactos">
<call-query href="contactos_registrados"/>
</operation>
</data>
I hope this coudl help you.

How do you access an element by its attributes value using XSL transforms and XML?

I gave current XML:
<element group="personalData" groupLabel="Сведения о личных данных" index="1" integrator-define="false" label="Фамилия" name="surname" type="textbox">FFF</element>
<element group="personalData" groupLabel="Сведения о личных данных" index="2" integrator-define="false" label="Имя" name="name" type="textbox">SSS</element>
<element group="personalData" groupLabel="Сведения о личных данных" index="3" integrator-define="false" label="Отчество" name="surname" type="textbox">KKK</element>
I want to access the value from the element where group="personalData" AND index="1", using XSL transformation.
Thank you very much.
try
<xsl:value-of select="element[#group='personalData' and #index='1']"/>
Shouldn't it be something like, 'data' should be replaced with the xpath to the xml nodes.
<xsl:value-of select="data[#group='personalData'] and data[#index='1']">

Need to create WSO2 DSS service which can read parameter from url

I have created a simple dss service which by inputing cust_id it gives me the customer data.
I have exposed this webservice as http get resource with the following url
GET /services/getCustDetailDSS/getDetail?cid=101
Corrsponding xml code for my service is as follows
<data name="getCustomerDetailDSS" serviceGroup="" serviceNamespace="">
<description/>
<config id="mydb">
<property name="carbon_datasource_name">mydb</property>
</config>
<query id="get_customer_detail" useConfig="mydb">
<sql>select identifier,user_status from customer_detail where identifier = :cid</sql>
<param name="cid" paramType="SCALAR" sqlType="STRING"/>
<result element="customer">
<element column="identifier" name="cid" xsdType="xs:string"/>
<element column="user_status" name="status" xsdType="xs:string"/>
</result>
</query>
<operation name="get_customer_detail_operation">
<call-query href="get_customer_detail">
<with-param name="cid" query-param="identifier"/>
</call-query>
</operation>
<resource method="GET" path="/getDetail">
<call-query href="get_customer_detail">
<with-param name="cid" query-param="cid"/>
</call-query>
</resource>
</data>
But now i want the dss service to read cust_id from url instead of passing it as a parameter.
i.e i want to hit dss service as
GET /services/getCustDetailDSS/cid/101/getDetail
How can i do this in DSS ?
Can anyone provide wat changes i need to do in my dss?
For GET /services/getCustDetailDSS/getDetail/cid/101
You have to edit your resource path as follows.
<resource method="GET" path="getDetail/cid/{cid}">
With WSO2 DSS 3.2.1, you can now define your query string parameter as below:
<param name="cid" sqlType="QUERY_STRING"/>
instead of:
<param name="cid" paramType="SCALAR" sqlType="STRING"/>
and your URL should look like:
.../getDetail?cid=101

WSO2 DSS 3.2.0/3.2.1 can't recognize named parameters within LIKE statements

I have created a simple Data Service using wso2 dss as follows.
Query : SELECT id, key, value, description FROM dbo.configs where key like '%:filter%'
Final XML :
<query id="select_all_configs_like_query" useConfig="default">
<sql>SELECT id, key, value, description FROM dbo.configs where key like '%:filter%' </sql>
<result element="configsCollection" rowName="configs">
<element column="id" name="id" xsdType="xs:integer"/>
<element column="key" name="key" xsdType="xs:string"/>
<element column="value" name="value" xsdType="xs:string"/>
<element column="description" name="description" xsdType="xs:string"/>
</result>
<param name="filter" sqlType="QUERY_STRING"/>
</query>
<operation name="select_all_configs_like_operation">
<call-query href="select_all_configs_like_query">
<with-param name="filter" query-param="filter"/>
</call-query>
</operation>
When I invoke the service it responds with an empty response. No Error on the console. Once I checked the database history, query is recorded as below
SELECT id, key, value, description FROM dbo.configs where key like '%:filter%'
Looks like parameter is not assigned to the actual query. Any Help?
You can use the Concat function within the SQL statement so for example CONCAT('%',:filter,'%')

Using input parameter as an optional input

Using wso2, DSS version 3.01, I am trying to have an input parameter that could be an optional parameter. A user can say, give me all the info for this specific code, or if a user does not specify any code, I want to give all the rows of data. Can you help?
Instead of creating a query for each optional parameter, you can also do the following:
<query id="selectEmployees" useConfig="default">
<sql>select * from Employees where (:employeeNumber is null or employeeNumber = :employeeNumber)</sql>
<result element="employees" rowName="employee">
<element column="lastName" name="last-name" xsdType="string"/>
<element column="firstName" name="first-name" xsdType="string"/>
<element column="email" name="email" xsdType="string"/>
<element column="salary" name="salary" xsdType="double"/>
</result>
<param defaultValue="#{NULL}" name="employeeNumber" ordinal="1" paramType="SCALAR" sqlType="INTEGER" type="IN"/>
</query>
<operation name="getEmployees">
<call-query href="selectEmployees">
<with-param name="employeeNumber" query-param="employeeNumber"/>
</call-query>
</operation>
Now you can call 'getEmployees' with 'employeeNumber' and get specific employee,
or you can call 'getEmployees' without 'employeeNumber' and get all employees.
(Calling without 'employeeNumber' is by omitting the 'employeeNumber' tag, or using 'xsi:nil="true"'.)
Obviously, you cannot query for the value 'null' this way.
ok soo for example
<query id="employeesByNumberSQL" useConfig="default">
<sql>select * from Employees where employeeNumber = ?</sql>
<result element="employees" rowName="employee">
<element column="lastName" name="last-name" xsdType="string"/>
<element column="firstName" name="first-name" xsdType="string"/>
<element column="email" name="email" xsdType="string"/>
<element column="salary" name="salary" xsdType="double"/>
</result>
<param name="employeeNumber" ordinal="1" paramType="SCALAR" sqlType="INTEGER" type="IN"/>
select * from Employees
You have two queries employeesByNumberSQL, employeesByNumberSQL1 these two are mapped togetemployeesByNumber and getemployeesByNumber2
Well you can make input parameters optional by giving default values to the input parameters. For example
<query id="MyQ" useConfig="myDS">
<sql>select cust_id,name from customer where cust_id = ?</sql>
<result element="Entries" rowName="Entry">
<element column="cust_id" name="cust_id" xsdType="string"/>
<element column="name" name="name" xsdType="string"/>
</result>
<param defaultValue="1" name="cust_id" sqlType="INTEGER"/>
</query>
Here if you do not mention the input parameters it will take the input parameter as one. Or else you need to create two queries and handle them programmatically