I am having a WS Proxy in Datapower . Both the client and the backends are HTTP . My request contains a soap header that has values like :
wsa:Action
wsa:MessageID
wsa:ReplyTo
timestamp
The backend doesnt require all these values , so they are stripped of before sending a cnverted request to the backend and obviously these are not there in the response which I get back from backend. Now when I send a response back to the client from Datapower , I need all these values back in the response soap headers . A
newly created timestamp which expires after 5 mins .
Action
MessageID
ReplyTo
Is there any way to put them back. I dont want to do it from xslt , as I beleive there is some inbuilt support from Datapower to handle this .
I would just store the entire SOAP-header node-set in a context variable and replace it in the response rule. Unless, of course the back-end adds or modifies specific values. In that case, you can pick and choose what to restore.
Please find below code tp remove header and to move it to context variable .
Further you can use that context variable values to place it back.
XSl1 : To save username and password into context variable`
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:dpconfig="http://www.datapower.com/param/config"
extension-element-prefixes="dp date dpconfig" exclude-result-prefixes=" dp dpconfig ">
<xsl:template match="/">
<xsl:variable name = "User">
<xsl:value-of select="/*[local-name()='Envelope']/*[local-name()='Header']/*[local-name()='Security']/*[local-name()='UsernameToken']/*[local-name()='Username']/text()"/>
</xsl:variable>
<xsl:variable name = "PWD">
<xsl:value-of select="/*[local-name()='Envelope']/*[local-name()='Header']/*[local-name()='Security']/*[local-name()='UsernameToken']/*[local-name()='Password']/text()"/>
</xsl:variable>
<xsl:message dp:priority="debug">
User name : <xsl:value-of select="$User"/>
<xsl:message dp:priority="debug">
Password : <xsl:value-of select="$PWD"/>
</xsl:message>
<dp:set-variable name="'var://context/Test/User'" value ="string($User)"/>
<dp:set-variable name="'var://context/Test/Pws'" value ="string($PWD)"/>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
<xsl:copy-of select="/*[local-name()='Envelope']/*[local-name()='Body']/*" />
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
XSl2 :To add back the Username and Password back into SOAP .
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:dpconfig="http://www.datapower.com/param/config"
extension-element-prefixes="dp dpconfig soapenv" exclude-result-prefixes="dp dpconfig">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match = "*[local-name() = 'Header']">
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:appid xmlns:soap="http://na.az.com/soaplatform">?</soap:appid>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>
<xsl:value-of select="dp:variable('var://context/Test/User')"/>
</wsse:Username>
<wsse:Password>
<xsl:value-of select="dp:variable('var://context/Test/Pws')"/>
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
</xsl:template>
</xsl:stylesheet>
Related
Since our company is moving from AX to SAP I'm also making a 'shift' from visual studio to eclipse. I'd thought it would be nice to start with a small xslt project but when trying my existing (made in VS) xsl I noticed some differences.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="msxsl:SalesType">
<xsl:choose>
<xsl:when test="(../msxsl:SalesType) = 'ReturnItem'">
<xsl:element name="MessageType" namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">384</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="MessageType" namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">380</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Generates an output xml with msxsl prefix xmlns:msxsl="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">380:
<?xml version="1.0" encoding="UTF-8"?>
<Envelope
xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
<Header>
<MessageId>{0E415D3C-6D46-4E4E-B8CA-9729B11BA}</MessageId>
<SourceEndpoint>BAB</SourceEndpoint>
<DestinationEndpoint>INVOIC_WKMP</DestinationEndpoint>
<Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesInvoiceService/read
</Action>
</Header>
<Body>
<MessageParts>
<SalesInvoice xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">
<CustInvoiceJour class="entity">
<AccountcategoryId>FFF</AccountcategoryId>
<msxsl:MessageType
xmlns:msxsl="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">380</msxsl:MessageType>
</CustInvoiceJour>
</SalesInvoice>
</MessageParts>
</Body>
</Envelope>
Whereas visual studio xsl leaves out the xmlns:msxsl specification (which is correct):
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Message">
<Header>
<MessageId>{0E415D3C-6D46-4E4E-B8CA-9729B11BA}</MessageId>
<SourceEndpoint>BAB</SourceEndpoint>
<DestinationEndpoint>INVOIC_WKMP</DestinationEndpoint>
<Action>http://schemas.microsoft.com/dynamics/2008/01/services/SalesSalesInvoiceService/read</Action>
</Header>
<Body>
<MessageParts>
<SalesInvoice xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice">
<CustInvoiceJour class="entity">
<AccountcategoryId>FFF</AccountcategoryId>
<MessageType>380</MessageType>
</CustInvoiceJour>
</SalesInvoice>
</MessageParts>
</Body>
</Envelope>
Since it’s already in the http://schemas.microsoft.com/dynamics/2008/01/documents/SalesInvoice namespace
I don’t want this addition here. Is there anything I can do to change this in eclipse?
Kind regards,
Mike
No, Visual Studio is NOT correct to omit this namespace. If you don't want it included you should explicitly omit it using xsl:exclude-result-prefixes="msxsl".
<?xml version="1.0" encoding="utf-8"?>
<Foo>
<Tier Path="\\10.10.44.61\Case Study\" />
<Force Path="\\10.10.44.61\Orto Study" Atomic="False" />
</Foo>
How can I read in powershell Tier Path value?
I am expecting to get the value of \\10.10.44.61\Case Study\
$xml = '<?xml version="1.0" encoding="utf-8"?>
<Foo>
<Tier Path="\\10.10.44.61\Case Study\" />
<Force Path="\\10.10.44.61\Orto Study" Atomic="False" />
</Foo>'
([xml]$xml).Foo.Tier.Path
As long as you are using an xml type (which I do by casting) you can reference the path directly as members of the object.
I've just created a webservice client in Perl using SOAP::Lite.
I manage to invoke a method of my webservice quite easily, but for some unknown reasons, it works sometimes, and sometimes it won't work.
Here's my perl client code :
my $client = SOAP::Lite->uri("http://loa.webservice")
->service("http://localhost:8888/LogAnalyzerWS/services/DataReceiver?wsdl");
my $res;
do {
sleep(2);
print ("ok \n");
$res = $client->sendData($data);
}while(!defined $res);
print $res, "\n";
I tried to add a while loop to resend the data if the result is undefined, but it won't work.
After some analysis of SOAP::Lite trace log file, I found that during the request, one parameter changes.
Here's the correct xml soap request :
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns:sendData>
<element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
</ns:sendData>
</soap:Body>
</soap:Envelope>
And the correct answer :
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:sendDataResponse xmlns:ns="http://webservice.loa">
<ns:return>1</ns:return>
</ns:sendDataResponse>
</soapenv:Body>
</soapenv:Envelope>
And here's the faulty xml request :
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns:sendData>
<element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
</ns:sendData>
</soap:Body>
</soap:Envelope>
With the answer :
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Action>http://www.w3.org/2005/08/addressing/soap/fault</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:VersionMismatch</faultcode>
<faultstring>Only SOAP 1.1 or SOAP 1.2 messages are supported in the system</faultstring>
<detail />
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
As you can see, xmlns:soap hasn't got the same value in the correct and the faulty request : for the correct one, it is :
"http://schemas.xmlsoap.org/soap/envelope/"
And for the faulty one, it is :
"http://schemas.xmlsoap.org/wsdl/soap/"
Any ideas why SOAP::Lite is changing this parameter on it's own ?
The problem comes from the way namespaces are handled in SOAP::Lite.
See this issue on RT cpan. Axis 2 was generating a wsdl which was then parsed by SOAP::Lite, and the value of xmlns:soap from the hash, set by the SOAP::Lite::Serializer, was wrongly being modified by the parsing of the wsdl.
To solve this problem, use this at the very begining of your code (before setting the wsdl in SOAP::Lite) :
$SOAP::Constants::PREFIX_ENV = 'SOAP-ENV';
Also one can use method envprefix:
$client->envprefix('SOAP-ENV');
This code works for me:
use SOAP::Lite +trace => [ qw(debug) ]; # to get all logging without transport messages
my $service = SOAP::Lite->service('https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL');
$service->soapversion('1.1');
$service->readable(1);
$service->envprefix('SOAP-ENV');
$service->bodyattr({ xmlns => 'http://web.cbr.ru/' });
my $result = $service->GetCursOnDate('2021-02-05T00:00:00');
I have a pipeline question.
I have a workflow where I have a master XML that references multiple XML files. It would be similar to a DITA map, but this is not DITA.
I am having to run an XSLT on the master XML to prepare it for a downstream process for output to the web or other medium.
Part of this transform includes resolving database file paths to relative file paths within the package that is exported from the content management system.
I can perform the transformation on the master XML just fine. However, my question involves running a XSLT on the referenced XML files. They also need the paths corrected.
Here is a simple sample...
<master>
<reference url="x-database01.xml"/>
</master>
The reference will resolve to something like url="/files/realXMLname.xml". The problem is that I don't know how to then transform realXMLname.XML to resolve the paths there.
<content>
<graphic href="x-database02.jpg"/>
</content>
The database and the downstream process are 2 different software packages with an out-of-the-box integration. I could write my own pipeline to do the transforms, but it may be cost prohibitive. The current integration only allows for 1 XSLT to be run a the pre-process step.
Is it possible to transform referenced XML files in a single XSLT transform step?
The following setup uses a main input XML input.xml which only contains a root node and two other XML files part1.xml and part2.xml which are read using the document() function. The XSLT uses <xsl:apply-templates> to trigger the conversion of the union of the two XML files. This way it should be possible to combine any number of XML files beforehand into one tree and execute the XSLT process on the resulting tree.
By the way: It turns out that this is already supported in XSLT 1.0 (at least by the xsltproc processor).
File input.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root/>
File part1.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root1>
<element>
<subelement1 message="Hello from part1.xml"/>
</element>
</root1>
File 'part2.xml':
<?xml version="1.0" encoding="ISO-8859-1"?>
<root2>
<element>
<subelement2 message="Hello from part2.xml"/>
</element>
</root2>
With the input above the following XSLT transformation
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:variable name="part1" select="document('part1.xml')/root1"/>
<xsl:variable name="part2" select="document('part2.xml')/root2"/>
<xsl:template match="/">
<messages>
<xsl:apply-templates select="$part1|$part2"/>
</messages>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
<xsl:template match="subelement1">
<message>
<xsl:value-of select="#message"/>
</message>
</xsl:template>
<xsl:template match="subelement2">
<message>
<xsl:value-of select="#message"/>
</message>
</xsl:template>
</xsl:stylesheet>
yields this output:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<message>Hello from part1.xml</message>
<message>Hello from part2.xml</message>
</messages>
I have the folllowing soap response. Now I want to replace the null value with a suitable value. How can I achieve it?
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soapenvelope">
<soapenv:Body>
<Entries xmlns="http://ws.wso2.org/dataservice">
<Entry>
<empId>xxx</empId>
<empName>yyy</empName>
<allocatedDesk>null</allocatedDesk>
</Entry>
</Entries>
</soapenv:Body>
</soapenv:Envelope>
You can use a XSLT to replace the "null":
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xpath-default-namespace="http://ws.wso2.org/dataservice" version="2.0">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/soapenv:*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="allocatedDesk[text()='null']">
<xsl:copy>
<xsl:value-of select="'YOUR DESIRED TEXT'"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*|node()|#*">
<!-- copy all elements -->
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The xslt mediator is being used to apply the XSLT on your MessageContext in WSO2. See the documentation:
http://wso2.org/project/esb/java/3.0.1/docs/mediators/xslt.html