XML Output Stage issue, missing namespace prefixes

Dedicated to DataStage and DataStage TX editions featuring IBM<sup>®</sup> Service-Oriented Architectures.

Moderators: chulett, rschirm

Post Reply
ameyvaidya
Charter Member
Charter Member
Posts: 166
Joined: Wed Mar 16, 2005 6:52 am
Location: Mumbai, India

XML Output Stage issue, missing namespace prefixes

Post by ameyvaidya »

Hi all,

Trying to test the webservices transformer to post data to a web service.

The webservice I've used is the Temperature Conversions service (Starting small as recommended here and elswhere(Thanks ernie for your amazing blogs)).

The web service page is:
http://xmethods.net/ve2/ViewListing.po? ... C8E4640281

This takes one input integer (I am using CtoF) and gets the Corresponding Farenheit value.

1. Imported WSDL and set up the following test rig:

Code: Select all

Transformer----->Web Services Transformer------>Seq File
(Working as 
a row gen, 
no IP's, 
1 stagevar)
This runs perfectly. Therefore we do not have any connectivity issues or issues with the web services stage (i hope).

2. Next test was to use the XML output stage to generate the Request Message chunk. Job design as follows:

Code: Select all

                               (This mirrors 
                                 the XML sent 
                                 to the WS transfm
                                 into a SeqFile).
Transformer----->XML Output----->Transformer----->Web Services Transformer------>Seq File
                                    |
                                    |
                                 Seq File
(Working as 
a row gen, 
no IP's, 
1 stagevar)
The XPath for the temp column as imported by the web service WSDL importer in CToF_IN tabledef is:

Code: Select all

/ns1:CtoF/temp[@xsi:type="xsd:int"]/text()
The XML chunk that i get for this XPath is:

Code: Select all

<:CtoF xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:TempConverterIntf-ITempConverter" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<temp :type="xsd:int">
53
</temp>
</:CtoF>
The issue is that i should be getting "</ns1:CtoF xmlns:..." and not "<:CtoF xmlns:..." from the XML Output Stage.

Another trial run with the XPath:

Code: Select all

/ns1:CtoF/temp/text()
produced

Code: Select all

<:CtoF xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:TempConverterIntf-ITempConverter" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<temp>
14
</temp>
</:CtoF>
This has been also tested out in PX with the same results.

Removing the namespace declarations from the XPath is not an option as (I believe) webservices tend to insist on the namespace being properly defined.
Using only the webservices stage without the XML output stage is also not an option as the final requirement is to build a job that calls a web service that needs a request formatted with 3 levels(??) of XML

Code: Select all

  <PO>
    <PO LIne
      <POLineSchedule>

Anyone faced this before?

:( .

Thanks in advance
Last edited by ameyvaidya on Mon May 19, 2008 12:29 am, edited 1 time in total.
Amey Vaidya<i>
I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.</i>
<i>- Douglas Adams</i>
eostic
Premium Member
Premium Member
Posts: 3838
Joined: Mon Oct 17, 2005 9:34 am

Post by eostic »

Hi....

Thanks for the kind words. I keep looking for good complex example to document in gory detail, beyond the explanation on the blog for ones that can be challenging.... I've done many, but not one recently. Maybe I should tear apart the Temp Conversion one further.

You are on the right track, and should be able to nail this by:

a) "load" the _IN table into the Input link of the XMLOutput Stage placed prior to your WSTransformer...

b) load the _OUT table into the Output link of the XMLInput Stage placed after your WSTransformer.

c) load the same tables into the corresponding Namespace tabs for each of the links above.

d) have a single column on the input link of the WSTransformer, coming from XMLOutput. It should have only a "slash" in its description. Give it a large char or varchar for datatype.

e) have a single column on the output link of the WSTransformer, going to XMLInput... place a single slash in its description. Same for datatype.

f) in the Message tab of Input and Output links on the WSTransformer, use the little pull-down that says "User Defined Column," and pick your single column.

This strategy should be ok for those services that are still single row in/out, and also those that use arrays but are 1:1 (array in and array out).

Complex SOAP bodies expand on this technique. Share the wsdl that you are using and we can work on it together.

Ernie
Ernie Ostic

blogit!
<a href="https://dsrealtime.wordpress.com/2015/0 ... ere/">Open IGC is Here!</a>
ameyvaidya
Charter Member
Charter Member
Posts: 166
Joined: Wed Mar 16, 2005 6:52 am
Location: Mumbai, India

Post by ameyvaidya »

Thanks for the response Ernie!!!

This is where i am as of now:
eostic wrote:
a) "load" the _IN table into the Input link of the XMLOutput Stage placed prior to your WSTransformer...
Done
eostic wrote: b) load the _OUT table into the Output link of the XMLInput Stage placed after your WSTransformer.
Not Done. I would like to get the input part done with before i try to decode the response message. As of now i use the Web Services Output link to provide me the Tabular form converted data.
eostic wrote: c) load the same tables into the corresponding Namespace tabs for each of the links above.
Done
eostic wrote: d) have a single column on the input link of the WSTransformer, coming from XMLOutput. It should have only a "slash" in its description. Give it a large char or varchar for datatype.
Done
eostic wrote: e) have a single column on the output link of the WSTransformer, going to XMLInput... place a single slash in its description. Same for datatype.
Not Done. Same as above.
eostic wrote: f) in the Message tab of Input and Output links on the WSTransformer, use the little pull-down that says "User Defined Column," and pick your single column.
Done

The WSDL is :

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservices.daehosting.com/temperature" name="TemperatureConversions" targetNamespace="http://webservices.daehosting.com/temperature">
  <types>
    <xs:schema elementFormDefault="qualified" targetNamespace="http://webservices.daehosting.com/temperature">
      <xs:element name="CelciusToFahrenheit">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="nCelcius" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="CelciusToFahrenheitResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="CelciusToFahrenheitResult" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="FahrenheitToCelcius">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="nFahrenheit" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="FahrenheitToCelciusResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="FahrenheitToCelciusResult" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="WindChillInCelcius">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="nCelcius" type="xs:decimal"/>
            <xs:element name="nWindSpeed" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="WindChillInCelciusResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="WindChillInCelciusResult" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="WindChillInFahrenheit">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="nFahrenheit" type="xs:decimal"/>
            <xs:element name="nWindSpeed" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="WindChillInFahrenheitResponse">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="WindChillInFahrenheitResult" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </types>
  <message name="CelciusToFahrenheitSoapRequest">
    <part name="parameters" element="tns:CelciusToFahrenheit"/>
  </message>
  <message name="CelciusToFahrenheitSoapResponse">
    <part name="parameters" element="tns:CelciusToFahrenheitResponse"/>
  </message>
  <message name="FahrenheitToCelciusSoapRequest">
    <part name="parameters" element="tns:FahrenheitToCelcius"/>
  </message>
  <message name="FahrenheitToCelciusSoapResponse">
    <part name="parameters" element="tns:FahrenheitToCelciusResponse"/>
  </message>
  <message name="WindChillInCelciusSoapRequest">
    <part name="parameters" element="tns:WindChillInCelcius"/>
  </message>
  <message name="WindChillInCelciusSoapResponse">
    <part name="parameters" element="tns:WindChillInCelciusResponse"/>
  </message>
  <message name="WindChillInFahrenheitSoapRequest">
    <part name="parameters" element="tns:WindChillInFahrenheit"/>
  </message>
  <message name="WindChillInFahrenheitSoapResponse">
    <part name="parameters" element="tns:WindChillInFahrenheitResponse"/>
  </message>
  <portType name="TemperatureConversionsSoapType">
    <operation name="CelciusToFahrenheit">
      <documentation>Converts a Celcius Temperature to a Fahrenheit value</documentation>
      <input message="tns:CelciusToFahrenheitSoapRequest"/>
      <output message="tns:CelciusToFahrenheitSoapResponse"/>
    </operation>
    <operation name="FahrenheitToCelcius">
      <documentation>Converts a Fahrenheit Temperature to a Celcius value</documentation>
      <input message="tns:FahrenheitToCelciusSoapRequest"/>
      <output message="tns:FahrenheitToCelciusSoapResponse"/>
    </operation>
    <operation name="WindChillInCelcius">
      <documentation>Windchill temperature calculated with the formula of Steadman</documentation>
      <input message="tns:WindChillInCelciusSoapRequest"/>
      <output message="tns:WindChillInCelciusSoapResponse"/>
    </operation>
    <operation name="WindChillInFahrenheit">
      <documentation>Windchill temperature calculated with the formula of Steadman</documentation>
      <input message="tns:WindChillInFahrenheitSoapRequest"/>
      <output message="tns:WindChillInFahrenheitSoapResponse"/>
    </operation>
  </portType>
  <binding name="TemperatureConversionsSoapBinding" type="tns:TemperatureConversionsSoapType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="CelciusToFahrenheit">
      <soap:operation soapAction="" style="document"/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="FahrenheitToCelcius">
      <soap:operation soapAction="" style="document"/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="WindChillInCelcius">
      <soap:operation soapAction="" style="document"/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="WindChillInFahrenheit">
      <soap:operation soapAction="" style="document"/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="TemperatureConversions">
    <documentation>Visual DataFlex Web Service to convert temperature values between Celcius and Fahrenheit</documentation>
    <port name="TemperatureConversionsSoap" binding="tns:TemperatureConversionsSoapBinding">
      <soap:address location="http://webservices.daehosting.com/services/TemperatureConversions.wso"/>
    </port>
  </service>
</definitions>


Continued in the next post for clarity.....
Amey Vaidya<i>
I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.</i>
<i>- Douglas Adams</i>
ameyvaidya
Charter Member
Charter Member
Posts: 166
Joined: Wed Mar 16, 2005 6:52 am
Location: Mumbai, India

Post by ameyvaidya »

The problem i am facing right now is with the XML Output Stage.

The XPath I get for the "temp" column when i import the CToF_IN tabledef is:

Code: Select all

/ns1:CtoF/temp[@xsi:type="xsd:int"]/text()
The XML chunk that <B>Ideally should</B> be generated considering the above xpath is:
______________________________
<<B>ns1:</B>CtoF xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:TempConverterIntf-ITempConverter" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<temp <B>xsi:</B>type="xsd:int">

53

</temp>

</<B>ns1:</B>CtoF>
_____________________________

Note the sections in Bold in the XML chunk above.

However what i get at the output of the XML Output stage is this:

Code: Select all

<:CtoF xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:TempConverterIntf-ITempConverter" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<temp :type="xsd:int">
53
</temp>
</:CtoF> 
Note that the NameSpace prefixes are missing (eg.: "<:CtoF " when it should have been "<ns1:CtoF") in the XML Output-generated chunk.

This is the first time I've had to use Namespaces in XML.
Otherwise I've used both the XML Input and output stages before without issue to generate and decode pretty complex XML docs.

:?
Thanks in Advance!!!
Amey Vaidya<i>
I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.</i>
<i>- Douglas Adams</i>
ameyvaidya
Charter Member
Charter Member
Posts: 166
Joined: Wed Mar 16, 2005 6:52 am
Location: Mumbai, India

Post by ameyvaidya »

Additionally,

If i use the following XML chunk (The Ideal XML chunk mentioned in the above post) and input it directly into the WEB Services Transformer stage, it works:

Code: Select all

<ns1:CtoF xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:TempConverterIntf-ITempConverter" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <temp xsi:type="xsd:int">
53
    </temp>
</ns1:CtoF>
So now I've pretty much narrowed my problem down to the following statement:

The XML Output Stage messes up the NameSpace Prefixes in the generated XML.
Any tips on this anyone?
Amey Vaidya<i>
I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.</i>
<i>- Douglas Adams</i>
eostic
Premium Member
Premium Member
Posts: 3838
Joined: Mon Oct 17, 2005 9:34 am

Post by eostic »

All these recent threads over the weekend inspired me to pull up some old .dsx's....and then I discovered that they didn't work anymore in v8 ! ......because of this exact issue that you hit....

...So I added this to my code:

A transformer between XMLOutput and WSTransformer, passing the single column of XML content thru it, and having this Derivation:

Ereplace(t2.SOAPbody,":array","ns1:array")

where "array" is enough of a substring to uniquely identify the service name (the highest level element name in the SOAP body).

Ernie
Ernie Ostic

blogit!
<a href="https://dsrealtime.wordpress.com/2015/0 ... ere/">Open IGC is Here!</a>
ameyvaidya
Charter Member
Charter Member
Posts: 166
Joined: Wed Mar 16, 2005 6:52 am
Location: Mumbai, India

Post by ameyvaidya »

Thanks, Ernie!!!

That is the workaround we were thinking of.. but I'd rather have the XML output stage work "as advertised".

This one is going to IBM as a bug and i'm marking this post as resolved: Workaround.

Thanks a ton for the assistance Ernie!!!!! As Craig mentioned recently, You're the (XML) man!!! Appreciate it!!
Amey Vaidya<i>
I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.</i>
<i>- Douglas Adams</i>
Post Reply