Including a CDATA field in a Service Connector - informatica

An API I am communicating with is Soap based and requires XML with inner XML (CDATA) in the request.
For the service connector action test I have hard-coded the inner xml with this format:
<![CDATA[
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationCrossReferenceId="123">
...
...
</Application> ]]>
where the dots indicate the data contained.
When running the test the request payload has been transformed to the html entity for < which is $lt; - as seen below :
Is there a way to avoid this?

This is a bug in Informatica. the other characters are decoded back to their original correctly, as described in KB 512858, &gt and &lt however are not decoded.
A bug report has been raised 29.05.2020.
Edit: Further investigation revealed that using CDATA was not necessary in my case, instead I was able to use the following input for the body binding:
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationCrossReferenceId="123">
...
...
</Application>

Related

Regarding <Results> Element/propery/Tag/Function in DataPower xslt

This may be somewhat naive but I am quite struck on the issue
There is a specific <result> element in DataPower and when calling through xslt we have somewhat following format(which I discovered in some forums)--
<results mode="require-all" multiple-outputs="true" transactional="true" retry-interval="100" asynchronous="false">
<url input="var://the_request_SOAP_Format"asynchronous="true">https://XXXXXXX</url>
now in this (url input) is the request which needs to be send and (https://XXXXXXX) is the specified backend where it needs to be sent
Now I have some authentication headers(httpHeaders) also which I need to send without which I will get Authorization error
<xsl:variable name="httpHeaders">
<header name="Content-Type">application/json</header>
<header name="Authorization">
<xsl:value-of select="concat('Bearer ',$some_sessionID)"/>
</header>
</xsl:variable>
Is this possible to add these 'httpHeaders' in the result mode element/Tab property
Thanks
I am not exactly sure what you are trying to achieve but adding http headers for the response (backside) you do with:
<dp:set-http-response-header name="'HeaderName'" value="$httpHeaders"/>
or
<dp:set-http-request-header name="'HeaderName'" value="$httpHeaders"/>
The <results> is the collection of data that the Processing Policy will output as Payload for the Request/Response and won't contain headers. You shouldn't try to alter the <results> object!
The "results-doc" method of calling backends is quite powerful, but I'm not sure from your question if you fully understand it. The url/#input attribute needs to be a DataPower context:
<url input="var://context/mycontext" ...
To associate headers with that context, you should do something like this for each header you need:
<dp:set-variable
name="'var://context/mycontext/_extension/header/Content-Type'"
value="'application/json'"/>
(This would be done in your XSLT code, separate from creating the "results" document, but before you use a Results Action to execute.)

Sending a SOAP Call

I'm learning how to send and receive a SOAP call. I have the required parameters available with me like username , password and the URL of the WSDL/WebService.I lso know a sample SOAP reply that I'm expecting which is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:infoLookupResponse xmlns:ns1="urn:vtsPhoneNumberLookup">
<phoneNumber xsi:type="xsd:string">4444444444</phoneNumber>
<Type xsi:type="xsd:string">Landline</Type>
<OCN xsi:type="xsd:string">2222</OCN>
<OVERALLOCN xsi:type="xsd:string">2103</OVERALLOCN>
<COMPANY xsi:type="xsd:string">ABC Inc</COMPANY>
<DBA xsi:type="xsd:string">ABC Inc</DBA>
<CommonName xsi:type="xsd:string">ABC</CommonName>
<HOLDINGCOMPANY xsi:type="xsd:string">ABC Communications Inc</HOLDINGCOMPANY>
<MANAGEMENT xsi:type="xsd:string"></MANAGEMENT>
<SMS xsi:type="xsd:string"></SMS>
</ns1:infoLookupResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I have gone through online stuff and based on my understanding, in order to send the SOAP request, I need to have a raw XML of the same format that I'm
expecting ( as mentioned above). The condition in my case is that a user will be submitting a phone number using an HTML Page and that will be sent as a SOAP
request expecting the aforementioned reply from the server.
In the above case, a user would have submitted 4444444444 as a phone number. So,I understand that I need to create raw XML type of phoneNumber and my questions is, do I need to create raw XML for Type,OCN,OVERALLOCN,COMPANY,DBA,CommonName,HOLDINGCOMPANY,MANAGEMENT and SMS as well?
Please let me know if there is anything wrong with what I have understood so far. Also, let me know if you would like me to paste some specific part of WSDL which will help you in answering/understanding my question.

XMLNS attribute removed by Slow Cheetah transformation

I'm trying to use Slow Cheetah to transform a Windows scheduled task config file. I'm simply trying to add "repetition" node information, like so:
ORIGINAL:
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2013-01-02T09:32:12.2196371</Date>
<Author>xxx</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2013-01-10T01:00:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
.....
</Task>
REQUIRED, ADDITIONAL XML
<CalendarTrigger>
<Repetition>
<Interval>PT300S</Interval>
</Repetition>
</CalendarTrigger>
To do this, I have the following transformation file:
<?xml version="1.0" encoding="utf-16" ?>
<Task version="1.2">
<Triggers>
<CalendarTrigger xdt:Transform="Insert">
<Repetition>
<Interval>PT300S</Interval>
</Repetition>
</CalendarTrigger>
</Triggers>
</Task>
The problem I'm having is that all attributes outside of the CalendarTrigger node are removed (and therefore making the resultant transformation config an invalid scheduled task format).
I have tried adding
xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xdt:Transform="SetAttributes" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"
to the Task node, but the attribute is then generated at CalendarTrigger level (and I cannot put this attribute on the original, because I then get "No element in the source document matches '/Task/Triggers' ").
Any pointers?
UPDATE:
The problem seems to be isolated to the xmlns attribute; if I try to include this in the 'Task' node of the original, I get "No element in the source document matches '/Task/Triggers'" - BUT changing this attribute to 'xmlns2' works fine and produces exactly what I need (albeit with an 'xmlns2' attribute!). Is this a known limitation of Slow Cheetah? Anyone know of a potential work-around?
That's because your xdt:Transform="Insert" is one level to high.
This should work:
<?xml version="1.0" encoding="utf-16" ?>
<Task xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Triggers>
<CalendarTrigger>
<Repetition xdt:Transform="Insert">
<Interval>PT300S</Interval>
</Repetition>
</CalendarTrigger>
</Triggers>
</Task>

not able to remove tags that "xsi:nil" in them via xslt

I have following xml which contains several xml tags with xsi:nil="true". These are tags that are basically null. I am not able to use/find any sxlt transformer to remove these tags from the xml and obtain the rest of the xml.
<?xml version="1.0" encoding="utf-8"?>
<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a">
<retrieveAllValues>
<messages xsi:nil="true" />
<existingValues>
<Values>
<value1> 10.00</value1>
<value2>123456</value2>
<value3>1234</value3>
<value4 xsi:nil="true" />
<value5 />
</Values>
</existingValues>
<otherValues xsi:nil="true" />
<recValues xsi:nil="true" />
</retrieveAllValues>
</p849:retrieveAllValues>
The reason of error you get
[Fatal Error] file2.xml:5:30: The prefix "xsi" for attribute "xsi:nil" associated with an element type "messages" is not bound.
is absence of prefix named "xsi" declared, you should specify it in root element such as:
<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<retrieveAllValues>
<messages xsi:nil="true" />
// other code...
update
If you could not change xml document you're receiving from webservice, you could try next approach(if this approach is acceptable for you):
Change your xslt document to process xml documents without specifying element prefixes
Set property namespaceAware of DocumentBuilderFactory to false
After this yout transformer shouldn't complain
It doesn't look like this is going to be possible in XSLT - because of the missing namespace declarations you have to parse the XML file with a non-namespace-aware parser, but all the XSLT processors I've tried don't get on well with such documents, they must rely on some information that is only present when parsing with namespace awareness enabled, even if the document in question doesn't actually contain any namespaced nodes.
So you'll have to approach it a different way, for example by traversing the DOM tree yourself. Since you say you're working in Java, here's an example using Java DOM APIs (the example runs as-is in the Groovy console, or wrap it up in a proper class definition and add whatever exception handling is required to run it as Java)
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.w3c.dom.ls.*;
public void stripNils(Node n) {
if(n instanceof Element &&
"true".equals(((Element)n).getAttribute("xsi:nil"))) {
// element is xsi:nil - strip it out
n.getParentNode().removeChild(n);
} else {
// we're keeping this node, process its children (if any) recursively
NodeList children = n.getChildNodes();
for(int i = 0; i < children.getLength(); i++) {
stripNils(children.item(i));
}
}
}
// load the document (NB DBF is non-namespace-aware by default)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document xmlDoc = db.parse(new File("input.xml"));
stripNils(xmlDoc);
// write out the modified document, in this example to stdout
LSSerializer ser =
((DOMImplementationLS)xmlDoc.getImplementation()).createLSSerializer();
LSOutput out =
((DOMImplementationLS)xmlDoc.getImplementation()).createLSOutput();
out.setByteStream(System.out);
ser.write(xmlDoc, out);
On your original example XML this produces the correct result:
<?xml version="1.0" encoding="UTF-8"?>
<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a">
<retrieveAllValues>
<existingValues>
<Values>
<value1> 10.00</value1>
<value2>123456</value2>
<value3>1234</value3>
<value5/>
</Values>
</existingValues>
</retrieveAllValues>
</p849:retrieveAllValues>
The empty lines are not actually empty, they contain the whitespace text nodes either side of the removed elements, as only the elements themselves are being removed here.

Getting and displaying data from database with xforms on submission

I have a database with an xml document in it, and I want to display a transformed xml on my xforms page, when the submission is sent (I'm using orbeon forms).
My solution is, that on the submission my servlet gets the xml from the database, writes it into a file, xslt transforms the xml tree (when and how should I do the transformation?), but I don't know, how to display this file on the xforms page. Maybe the replace="instance" attribute in can help, but i don't know how.
Thanks!
Now, after Alessandro's advice, Im trying to use this xpl thing, but it doesn't work.
In the model:
<xforms:insert nodeset="instance('inst2')"
origin="xxforms:call-xpl('oxf:/resources/pipeline.xpl', 'data',
instance('inst1'), 'data')"/>
in pipeline.xpl:
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:oxf="http://www.orbeon.com/oxf/processors">
<p:param type="input" name="data"/>
<p:param type="output" name="data"/>
<p:processor name="oxf:xslt">
<p:input name="data" href="#data"/>
<p:input name="config" href="transform.xsl"/>
<p:output name="data" ref="data"/>
</p:processor>
My instance, that I want to transform is "complaint-instance", the transformed instance called "trf-instance", the pipeline.xpl file is in the same directory with my xforms page. My styesheet called customerToOperator.xsl. What's wrong in my code?
I just noticed, the note: "If you are using separate deployment, the service and XSLT transformation must be present in the Orbeon WAR file, instead of within your application."
Ehm... Where should I put these files?
my app in details:
a) an xforms page, with 2 instances:
<instance id='inst1'>
<name>
<lastname/>
<firstname/>
</name>
</instance>
<instance id='inst2'>
<fname>
<fullname/>
</fname>
</instance>
I got 2 input fields, referenced on name/lastname and name/firstname.
I have an xforms:insert node, described above, and an xforms:submission node:
<xforms:submission
id="save-submission"
ref="instance('inst2')"
action="/my-servlet"
method="post"
replace="none">
I added 2 files to orbeon/WEB-INF/resources, the pipeline.xpl, (described above) and transform.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<fname>
<fullname>
<xsl:value-of select="name/firstname"/>
<xsl:value-of select="name/lastname"/>
</fullname>
</fname>
</xsl:template>
</xsl:stylesheet>
And I have a servlet, which writes the posted instance on the console (now it writes inst2 on the console, but without the user input data, only the nodes...)
A really need to fix this...
Thanks again!
To get the XML from a database (relational or not) and apply a transformation, instead of writing my own servlet, I would use an XPL pipeline, and map this pipeline to a URL through the page flow. Now you have a service that answers to an HTTP request and returns XML. To call the service from XForms, you use an <xforms:submission replace="instance">. You end up with the XML in an instance, and you can display it with something like: <xforms:output value="saxon:serialize(instance(), 'xml')"/>.
In all cases (including separate deployment), the pipeline and XSLT file must be in the "resources". Usually, this means the WEB-INF/resources of the Orbeon's web app. But you can also do more fancy things by setting up the Orbeon resource manager to also use other directories on disk.