BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
TedP
Obsidian | Level 7

I need to send a stream of XML from a third party to a SAS stored process (which I deployed as a web service) and return some XML.

 

I believe I am very close as I have sent XML with parameters to a webservice with a correct response. For example I created addfloats webservice and sent the following data

<addfloats xmlns="http://tempuri.org/addfloats">
 <parameters>
 <num1>2</num1>
 <num2>4</num2>
 </parameters>
</addfloats>

with a post request to https://mysite.com:port/SASBIWS/rest/addfloats which results in a prefect response.

 

I desire to stream in data to a web service named xmlwebout. Here is the underlying stored process

 %put &tablename;

libname _WEBOUT xml xmlmeta = &_XMLSCHEMA;
libname instream xml;

proc means data=instream.&tablename;
   output out=_WEBOUT.mean;
run;

libname _WEBOUT clear;
libname instream clear;

In the making of the stored process I create an input parameter and input data source (named instream) and post the following data

<xmlwebout xmlns="http://tempuri.org/xmlwebout">
<Parameter name="tablename">InData</Parameter>
<Stream name="instream">
<Table>
<InData>
<Column1>1</Column1>
<Column2>20</Column2>
<Column3>99</Column3>
</InData>
<InData>
<Column1>50</Column1>
<Column2>200</Column2>
<Column3>9999</Column3>
</InData>
<InData>
<Column1>100</Column1>
<Column2>2000</Column2>
<Column3>1000000</Column3>
</InData>
</Table>
</Stream>
</xmlwebout>

 When I post this data I get the following error: 

HTTP Status 500 - Request processing failed; nested exception is com.sas.web.services.WSException: Expected stream 'instream' was not specified.

 

This example is laid out in the BI web services developer's guide. The difference between my version and the developer's guide is that I've deployed it as a web service and am using XML and not SOAP.

 

https://support.sas.com/documentation/cdl/en/wbsvcdg/64883/PDF/default/wbsvcdg.pdf

 

1 ACCEPTED SOLUTION

Accepted Solutions
TedP
Obsidian | Level 7

I found a solution after literally 40 hours of hardship and heartache and no solution from tech support. 

 

Unfortunately the documentation is sorely lacking of concrete examples of sending streams of data through plain XML. I was initially trying to just insert the plain XML part of the lone example SOAP request in the XMLA part of the documentation but my stream 'instream' was unable to be located.

 

The key to the solution was to look at the wsdl file (just append ?wsdl to the endpoint. ex: https://mycompany.com:port/SASBIWS/services/path/to/process/process_name?wsdl) I had gotten a simple addint stored process to return successfully and noticed that in my new stored process that the wsdl did not match the example in the developers guide. Here is the pertinent part of the wsdl for the stored process that streamed data.

 

<xsd:complexType name="upload_stream5Streams">
<xsd:sequence>
<xsd:element name="instream">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Value">
<xsd:complexType>
<xsd:sequence>

I needed separate elements for streams, instream, and Value, which is absolutely nowhere across the internet as far as I know.

 

Here is the complete XML

 

<upload_stream5>
<streams>
<instream>
<Value>
<Table>
 <InData >
 <Column1>1</Column1>
 <Column2>20</Column2>
 <Column3>99</Column3>
 </InData>
 <InData>
 <Column1>50</Column1>
 <Column2>200</Column2>
 <Column3>9999</Column3>
 </InData>
 <InData>
 <Column1>100</Column1>
 <Column2>2000</Column2>
 <Column3>1000000</Column3>
 </InData>
 </Table>
 </Value>
 </instream>
</streams>
</upload_stream5>

And here is the actual stored process sas code. Its a bit different than the developer's example because there is no _XMLSCHEMA macro variable. (tablename is defaulted to InData but you can pass this with XML as well using <parameters> and <parameter_name> tags)

 

%put &tablename;
libname otstream xml xmlmeta = SchemaData;
libname instream xml;
proc means data=instream.&tablename;
 output out=otstream.mean;
run;
libname otstream clear;
libname instream clear;

 

View solution in original post

5 REPLIES 5
TedP
Obsidian | Level 7

Stil no luck. If anybody has successfully completed the example from the developers guide (https://support.sas.com/documentation/cdl/en/wbsvcdg/64883/PDF/default/wbsvcdg.pdf) starting on page 19 (sample proc means) could you please post your exact XML here and the post request you used to generate the expected output.

 

Can I offer a bounty for this? I would pay quite a bit to have this.

TedP
Obsidian | Level 7

I found a solution after literally 40 hours of hardship and heartache and no solution from tech support. 

 

Unfortunately the documentation is sorely lacking of concrete examples of sending streams of data through plain XML. I was initially trying to just insert the plain XML part of the lone example SOAP request in the XMLA part of the documentation but my stream 'instream' was unable to be located.

 

The key to the solution was to look at the wsdl file (just append ?wsdl to the endpoint. ex: https://mycompany.com:port/SASBIWS/services/path/to/process/process_name?wsdl) I had gotten a simple addint stored process to return successfully and noticed that in my new stored process that the wsdl did not match the example in the developers guide. Here is the pertinent part of the wsdl for the stored process that streamed data.

 

<xsd:complexType name="upload_stream5Streams">
<xsd:sequence>
<xsd:element name="instream">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Value">
<xsd:complexType>
<xsd:sequence>

I needed separate elements for streams, instream, and Value, which is absolutely nowhere across the internet as far as I know.

 

Here is the complete XML

 

<upload_stream5>
<streams>
<instream>
<Value>
<Table>
 <InData >
 <Column1>1</Column1>
 <Column2>20</Column2>
 <Column3>99</Column3>
 </InData>
 <InData>
 <Column1>50</Column1>
 <Column2>200</Column2>
 <Column3>9999</Column3>
 </InData>
 <InData>
 <Column1>100</Column1>
 <Column2>2000</Column2>
 <Column3>1000000</Column3>
 </InData>
 </Table>
 </Value>
 </instream>
</streams>
</upload_stream5>

And here is the actual stored process sas code. Its a bit different than the developer's example because there is no _XMLSCHEMA macro variable. (tablename is defaulted to InData but you can pass this with XML as well using <parameters> and <parameter_name> tags)

 

%put &tablename;
libname otstream xml xmlmeta = SchemaData;
libname instream xml;
proc means data=instream.&tablename;
 output out=otstream.mean;
run;
libname otstream clear;
libname instream clear;

 

jcbell
Obsidian | Level 7

Just a quick thanks - The documentation is way off on this one and this was a big help.  

 

This may help someone else - 

 

This was my request file for Proc Soap.  This STP has a couple of input parameters and a instream table.

 

data _null_;
file request;
input;
put _infile_;
datalines4;
<?xml version="1.0"?>
<soapenv:Envelope xmlns:m="http://tempuri.org/stp_import_models"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> >
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
<m:basicWebService>

<m:parameters>
<m:_envusersk> 49 </m:_envusersk>
<m:_getmodelnamesonly> NO </m:_getmodelnamesonly>

</m:parameters>
<m:streams>
<m:instream>
<m:Value>
<Table>
<InData>
<uuid>a43f9000-0a14-0a6f-70de-c70aca70f6d9 </uuid>
</InData>
<InData>
<uuid>0baecef9-0a14-0a6f-6ff1-c22da43b0bda</uuid>
</InData>
<InData>
<uuid>07a45659-0a14-0a6f-6ff1-c22dc46c4391</uuid>
</InData>
</Table>
</m:Value>
</m:instream>
</m:streams>

</m:basicWebService>
</soapenv:Body>
</soapenv:Envelope>
;;;;
run;

 

 

blah349236
Calcite | Level 5

Thank you, thank you, thank you!!!!!

 

SAS doco is extraordinarity lacking for Web Services. The doco that is there is not clear and certainly incomplete.

hsoneji
Fluorite | Level 6

I tried the same example, doesn't work for me in SAS 9.4

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 3851 views
  • 7 likes
  • 4 in conversation