For partners that build or integrate commercially available applications and service solutions with the Oracle Cloud Platform
For partners that provide implementation or managed services around Oracle Cloud Applications
Implementing the suggestion in this topic - Include mapped output as the value of another output..., I need to get the text content of an XML node returned from a REST Adapter invoke so I can encode it to Base64. I tried just passing the node to the encodeBase64 function, but it encoded the text representation of the node itself (i.e. element name, attributes, etc...) rather than the text content of the node. It seems that the way to do this is with a for-each and then get-content-as-string, but I am unable to add a for-each as the input to the encode function. I thought to assign the value to a variable, but I can't use an XSLT expression in variables. It seems I could just map the node directly to the input of the function, but the node type is any, rather than string, even though it has a type of string in the sample file I used to define the response for the REST Adapter. I'm sure there is a way to do this. What am I missing?
I tried just passing the node to the encodeBase64 function, but it encoded the text representation of the node itself (i.e. element name, attributes, etc...) rather than the text content of the node.
A hint of xml and what you passed, your expectation and actual result will help us understand your problem and provide solution. I did not fully get the next part of what you mentioned on what are you trying here. Can you explain the issue you have with an example?
The XML returned from the service looks like:
<soapenv:Envelope xmlns="http://xmlns.oracle.com/cloud/adapter/nxsd/surrogate/response/SaveSalesOrder/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://xmlns.oracle.com/cloud/adapter/nxsd/surrogate/response/SaveSalesOrder/" xmlns:wss="http://www.adonix.com/WSS" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<wss:saveResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<saveReturn xsi:type="wss:CAdxResultXml">
<messages>
<type>2</type>
<message>This reference already exists for this customer!</message>
</messages>
<messages>
<type>2</type>
<message>Authorized credit level reached</message>
</messages>
<messages>
<type>2</type>
<message>Authorized credit level reached 7000000 USD</message>
</messages>
<resultXml xsi:type="xsd:string">
{"SOH0_1":{"SALFCY":"015","SOHNUM":"SO004341"}}</resultXml>
<status xsi:type="xsd:int">1</status>
</saveReturn>
</wss:saveResponse>
</soapenv:Body>
</soapenv:Envelope>
This is the same XML snippet that I used to configure the REST Adapter response. My expectation is that I could map to a stage file write using the opaque schema xsd with
<xsl:value-of select = 'oraext:encodeBase64($SaveSalesOrder/nsmpr9:executeResponse/nsmpr3:Envelope/nsmpr3:Body/nsmpr3:saveResponse/nsmpr3:saveReturn/nsmpr3:resultXml)'>
But this appears to base64Encode the instance id, e.g.
oracle.xml.parser.v2.XMLNodeList@54c016a1
I also tried
<xsl:value-of select='oraext:encodeBase64(oraext:get-content-as-string($SaveSalesOrder/nsmpr2:executeResponse/nsmpr5:Envelope/nsmpr5:Body/nsmpr5:saveResponse/nsmpr5:saveReturn/nsmpr5:resultXml))' />
but it encoded the string representation of the entire XML element, e.g.
<ns1:resultXml type="type562" xmlns:ns1="http://xmlns.oracle.com/cloud/adapter/nxsd/surrogate/response/SaveSalesOrder/">This is a test</ns1:resultXml>
I just want it to encode the text content of the resultXml node, in my example, the JSON string
{"SOH0_1":{"SALFCY":"015","SOHNUM":"SO004341"}}
The rest sample xml configuration supports only no namespace or single namespace but the sample you show has multiple namespaces, not sure how would it work!
Regarding the text content, can you try using xsl:copy-of instead of xsl:value-of like below
<xsl:copy-of select='oraext:encodeBase64(oraext:get-content-as-string($SaveSalesOrder/nsmpr2:executeResponse/nsmpr5:Envelope/nsmpr5:Body/nsmpr5:saveResponse/nsmpr5:saveReturn/nsmpr5:resultXml))' />
I removed namespaces in the sample I used. I don't understand how copy-of will address the issue which is that the mapped value of the node is not the node contents, but rather some representation of the node itself. I'll get the XSD and post it here so you can see that. Maybe the problem is how the schema was created from my sample.
I modified my sample to remove the CDATA thinking that might cause the problem. It did change the type of resultXml to string, but I am still not able to access the string value. If I try to log the value, i get an error "faultName: {{http://schemas.xmlsoap.org/ws/2003/03/business-process/}selectionFailure} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage} parts: {{ summary=<summary>The <from> value is invalid. Xpath expression associated with <from> in copy assign activity is invalid. There is an user error that results in missing element value(s) in the xpath query. Please review the payload and modeling to ensure that all elements defined in the <from> xpath query have valid non-null values . </summary> ,activity=<activity>540008-BpAss38-BpSeq33.60-3</activity> ,query=<query>$messagecontext_161.parameters/../nsmpr9:executeResponse/nsmpr3:Envelope/nsmpr3:Body/nsmpr3:saveResponse/nsmpr3:saveReturn/nsmpr3:resultXml</query> ,lineNumber=<lineNumber>1618</lineNumber>}" If I don't log the value, it fails the condition which checks for resultXml to not be nil. I have tried making the condition count(resultXml > 0) and that fails as well.
The actual xml has multiple namespaces but your expression has single namespace for entire xpath and it is expected to fail.
One way is to use local-name() like - $Response/*[local-name()='Envelope']/*[local-name()='Body']/....
That makes sense. Given that you cannot have multiple namespaces in an XML sample and I can't change the output to not have namespaces, this would seem to be the only way to make this work?
Hopefully Yes! And there is one other way you can try -
Get the REST response in raw format - This will be written to a stage file.
Create multiple schemas per namespaces, archive them and use it in stage read and see if you are able to read the response.
The actual xml has multiple namespaces but your expression has single namespace for entire xpath and it is expected to fail.
One way is to use local-name() like - $Response/*[local-name()='Envelope']/*[local-name()='Body']/....