In simple message flow in which there are 3 nodes. One is MQ input node which is receiving an xml input. Other is MQ Output node which is receiving msg passed from MQ input. In between there is trace node. The trace node is configured to generate trace in a file. it trace down the whole xml msg, its content in the file. What if I want to track a single tag of xml file like contact number.
i.e:
<contactDetails>
<contactName>Acme</contactName>
<contactNumber>09200209</contactNumber>
</contactDetails>
Which pattern should I use? I have tried ${Body.contactDetails.contactNumber} and ${Environment.contactDetails.contactNumber} but I am getting null in output. Can anyone help?
EDIT: Below is the whole message:
<?xml version="1.0" encoding="utf-8"?>
<tns:In_Request xmlns:tns="http://www.ibm.lab.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ActionRequest>O</ActionRequest>
<DateRequest>10/12/2005</DateRequest>
<customerNumber>1</customerNumber>
<customerName>ACME Hardware</customerName>
<customerDetails>
<customerAddress1>1254 Main St</customerAddress1>
<customerAddress2>Suite 12</customerAddress2>
<customerCity>Dime Box</customerCity>
<customerState>TX</customerState>
<customerCountry>USA</customerCountry>
<customerPostalCode>76543</customerPostalCode>
<customerCreditLimit>1200</customerCreditLimit>
<customerCreditScore>123</customerCreditScore>
</customerDetails>
<contactDetails>
<contactFirstName>Freddy</contactFirstName>
<contactLastName>Bloggs</contactLastName>
<contactPhoneNumber>555-123-6543</contactPhoneNumber>
</contactDetails>
<requestDecision>Y</requestDecision>
<comments>Just a Comment</comments>
</tns:In_Request>
I see the problem now.
Body in the reference points to the root element for the domain in which your message is parsed, e.g. to Root.XMLNSC if you set the message domain to XMLNSC on the input node of your message, so not to the root element of your message.
If you want to trace the value of the element contactPhoneNumber from the example message, you should use the following reference:
${Body.*:In_Request.contactDetails.contactPhoneNumber}
So after the Body, you must specify the whole path to your element. The *: part is needed because the root element in your message is in a namespace.
Related
I need to have first node of below xml that is inside of FIToFICstmrCdtTrf. However, xpath returns binary data.
xpath(xml(triggerBody()),'/')
xpath(xml(triggerBody())x,'/FIToFICstmrCdtTrf')
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">
<FIToFICstmrCdtTrf>
<GrpHdr>
<MsgId>x</MsgId>
<CreDtTm>x</CreDtTm>
<NbOfTxs>2</NbOfTxs>
....
Your XML is bound to the namespace urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02, so unless you register the namespace in order to be able to use a namespace-prefix in your XPath, you need to address the elements by their local-name().
For instance: /*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]
and then to select the first child element (GrpHdr), you can append a generic expression selecting any element * and apply a predicate filter to select the first: /*[1]
Putting it all together:
xpath(xml(triggerBody()),
'/*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]/*[1]')
After reproducing from my end, I was able to get this working by applying the below expressions in the flow of my logic app:
xpath(xml(variables('XML')),'/*[local-name()="Document"]/*[local-name()="FIToFICstmrCdtTrf"]/*')?[0]
OR
xpath(xml(variables('XML')),'/*[name()="Document"]/*[name()="FIToFICstmrCdtTrf"]/*')?[0]
Below is the flow of my logic app
RESULTS:
I am now trying another xpath property transfer in SoapUI, and am struggling again.
Rather than specifics I thought I would ask some general questions.
If the response I am wanting to extract from has a line like this:
<ns2:getApprovedPortChangeRequestsResponse xmlns:ns2="http://transferobjects.abc.abc.org">
Oddly, when I click the ns: button in SoapUI it generates the following:
declare namespace soap='http://schemas.xmlsoap.org/soap/envelope/';
declare namespace ns1='http://transferobjects.abc.abc.org';
declare namespace ns2='http://abc.abc.org/api/serviceorder';
But the message response is pretty clear with the ns2 line above
Then I think that I can safely assume that I should do this:
declare namespace ns2='getApprovedPortChangeRequestsResponse';
Now, when I do the part describing what I want to capture, I am using the ns2 tag, following by the section names that follow as I go in to the message, in this case two layers:
//ns2:return/approvedPortChangeRequests/#version
The value I want is the value of the field called version, don't know if I want the # symbol this time, it's a numeric value, but I get null regardless of whether the # is there or not. I have thoroughly checked the response message and pretty certain I have it right. There are a couple of other sections in the response above the field, but they are at the same level as , from what I can see.
I have tried including the getApprovedPortChangeRequestsResponse as a parent layer in the last line, with no effect.
Only when I use getApprovedPortChangeRequestsResponse in the ns2 declaration can I get anything other than Null, and then only verbose errors like this:
[net.sf.saxon.trans.XPathException: XPath syntax error at char 7 on line 2 in {\n//ns2:/return}:
QName cannot end with colon: {ns2:}]
Basically, I am utterly ignorant and my googlefu hasn't shown me any resource where I can build any sort of understanding of what I am doing, so any suggestion on that front would be appreciated. I just need a couple of examples of doing this in SoapUI, and I should be sweet.
Thanks in advance.
EDIT- Full Response here:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getApprovedPortChangeRequestsResponse xmlns:ns2="http://transferobjects.abc.abc.org">
<return>
<success>true</success>
<approvedPortChangeRequests>
<lspOverride>false</lspOverride>
<numbers>
<complete>false</complete>
<gainingCompanyId>11667</gainingCompanyId>
<losingCompanyId>11657</losingCompanyId>
<notRequired>false</notRequired>
<phoneNumber>
<phoneNumber>098453509</phoneNumber>
</phoneNumber>
</numbers>
<DateTimeStart>2018-03-07T08:00:00+13:00</DateTimeStart>
<som>6001309</som>
<category>Simple</category>
<requestDateTime>2018-03-07T12:05:25+13:00</requestDateTime>
<requesterResellerId>21</requesterResellerId>
<responderResellerId>1</responderResellerId>
<responseDue>
<actualDays>0</actualDays>
<actualHours>1</actualHours>
<actualMinutes>47</actualMinutes>
<businessDays>0</businessDays>
<businessHours>1</businessHours>
<businessMinutes>47</businessMinutes>
<negative>false</negative>
</responseDue>
<status>
<status>Awaiting APC Approval</status>
</status>
<version>1</version>
</approvedPortChangeRequests>
</return>
</ns2:getApprovedPortChangeRequestsResponse>
</soap:Body>
</soap:Envelope>
In your payload, version is an element rather than an attribute, so you don't need the #.
soapUI tries to help you out by declaring namespaces, but you can go simpler. If version is all you need and there's only one, you can navigate directly to it regardless of namespaces by using //version. The // notation will select a node no matter where it is in the payload.
Would it be possible for somebody provide me with example of the ACAGetTransmitterBulkRequestStatus web service response with errors?
I would like to see structure of the attached(if it's in attachment) errors.
Here's an XML with rejection errors:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:FormBCTransmitterSubmissionDtl xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:ns2="urn:us:gov:treasury:irs:common" xmlns:ns3="urn:us:gov:treasury:irs:msg:form1094-1095BCtransmittermessage">
<ACATransmitterSubmissionDetail>
<TransmitterErrorDetailGrp>
<SubmissionLevelStatusCd>Rejected</SubmissionLevelStatusCd>
<UniqueSubmissionId>1095C-16-0000XXXX|1</UniqueSubmissionId>
</TransmitterErrorDetailGrp>
<TransmitterErrorDetailGrp>
<UniqueSubmissionId>1095C-16-0000XXXX|1</UniqueSubmissionId>
<ns2:ErrorMessageDetail>
<ns2:ErrorMessageCd>AIREX126</ns2:ErrorMessageCd>
<ns2:ErrorMessageTxt>Rejected submission - TIN Validation Failed for ALE Member's EIN</ns2:ErrorMessageTxt>
<ns2:XpathContent>EmployerEIN</ns2:XpathContent>
</ns2:ErrorMessageDetail>
</TransmitterErrorDetailGrp>
<TransmitterErrorDetailGrp>
<UniqueRecordId>1095C-16-0000XXXX|1|3</UniqueRecordId>
<ns2:ErrorMessageDetail>
<ns2:ErrorMessageCd>AIRTN500</ns2:ErrorMessageCd>
<ns2:ErrorMessageTxt>TIN Validation Failed</ns2:ErrorMessageTxt>
</ns2:ErrorMessageDetail>
</TransmitterErrorDetailGrp>
</ACATransmitterSubmissionDetail>
</ns3:FormBCTransmitterSubmissionDtl>
You can recreate that same error response by sending invalid EIN's and SSN's that AATS doesn't expect.
If you want to send valid test EIN's, TIN's and names (outside of the IRS AATS test scenarios), please refer to https://www.irs.gov/pub/irs-pdf/p5164.pdf (starting at page 6).
Sample range of valid test EIN's:
EIN RANGE NAME CONTROL
00-0000001 through 00-0000100 HELP
00-0000101 through 00-0000200 HIDE
Sample range of valid test SSN's:
SSN RANGE NAME CONTROL
000-00-0001 through 000-00-0100 HERR
000-00-0101 through 000-00-0200 MART
I'm parsing an xml String using the 'evaluate' function provided by Xpath to read the contents embedded within specific tags in the xml. But i'm having trouble while trying to parse an xml which is embeded within a set of tags which i want to parse.
<Channel>
<channelId>SD0987</channelId>
<parameters>
<param>org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [https://nike-dev.coupahost.com/api/suppliers?return_object=limited]; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request</param>
<param><?xml version="1.0" encoding="UTF-8"?>
<errors>
<error>
<![CDATA[Unable to find valid PaymentTerm record for payment_term with keys {"code"=>"9999"}. Possible keys are ["id", "code"]. Please verify your xml.]]>
</error>
</errors>
</param>
<param>6-5100</param>
<param><?xml version="1.0" encoding="UTF-8"?><supplier><name>SuTestVDR008-6-5100</name><display-name>SuTestVDR008-6 (SANDALS) - VAT Registration Number - Indirect Europe - INACTIVE</display-name><status>active</status><deleted type="boolean">true</deleted><vendor-account-group-code>1001</vendor-account-group-code><vendor-number>SuTestVDR008-6</vendor-number><on-hold type="boolean">false</on-hold><language-code>E</language-code><purchase-organization-code>5100</purchase-organization-code><group-key>1234</group-key><vendor-partner-type-code>Z4</vendor-partner-type-code><currency-code>EUR</currency-code><primary-address><street1>#### JIU BI VILLAGE</street1><street2>77774</street2><city>GUANGZHOU CITY</city><state>190-Guangdong</state><postal-code>511480</postal-code><country><code>CN</code></country></primary-address><payment-term><code>9999</code></payment-term><content-groups><content-group><name>730_Company Code</name></content-group></content-groups><po-method>prompt</po-method><invoice-matching-level>3-way</invoice-matching-level></supplier></param>
</parameters>
</Channel>
In the above xml sample, i need to read and retrieve everything that is within the tags "param".
Currently, i'm first getting a count of the param tags and then looping thru them to get the data within the tags -
paramCount = XPathUtils.evaluate(originalPayload,"count(/Channel/parameters/param)",XPathUtils.STRING);
for(int i=1;i<=pCount;i++){
pList.add(XPathUtils.evaluate(originalPayload, "/Channel/parameters/param[" +i+ "]",XPathUtils.STRING)
}
This works fine with other xmls but not with the sample given above. I get the below error -
"[Fatal Error] :5:17:The processing instruction target matching "[xX][mM][lL]" is not allowed."
If i remove the part "?xmlversion="1.0" encoding="UTF-8"?
it parses the tags but the output is -
org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [https://nike-dev.coupahost.com/api/suppliers?return_object=limited]; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Unable to find valid PaymentTerm record for payment_term with keys {"code"=>"9999"}. Possible keys are ["id", "code"]. Please verify your xml.
6-5100
SuTestVDR008-6-5100SuTestVDR008-6 (SANDALS) - VAT Registration Number - Indirect Europe - INACTIVEactivetrue1001SuTestVDR008-6falseE51001234Z4EUR#### JIU BI VILLAGE77774GUANGZHOU CITY190-Guangdong511480CN9999730_Company Codeprompt3-way
So as you can see, it just captured the content within the various tags and printed it.
My ask is to print all the text in between the
<param >
tags as is with all the indentation in place.
So the output expected is -
org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [https://nike-dev.coupahost.com/api/suppliers?return_object=limited]; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<errors>
<error>
<![CDATA[Unable to find valid PaymentTerm record for payment_term with keys {"code"=>"9999"}. Possible keys are ["id", "code"]. Please verify your xml.]]>
</error>
</errors>
6-5100
<?xml version="1.0" encoding="UTF-8"?>
<supplier><name>SuTestVDR008-6-5100</name><display-name>SuTestVDR008-6 (SANDALS) - VAT Registration Number - Indirect Europe - INACTIVE</display-name><status>active</status><deleted type="boolean">true</deleted><vendor-account-group-code>1001</vendor-account-group-code><vendor-number>SuTestVDR008-6</vendor-number><on-hold type="boolean">false</on-hold><language-code>E</language-code><purchase-organization-code>5100</purchase-organization-code><group-key>1234</group-key><vendor-partner-type-code>Z4</vendor-partner-type-code><currency-code>EUR</currency-code><primary-address><street1>#### JIU BI VILLAGE</street1><street2>77774</street2><city>GUANGZHOU CITY</city><state>190-Guangdong</state><postal-code>511480</postal-code><country><code>CN</code></country></primary-address><payment-term><code>9999</code></payment-term><content-groups><content-group><name>730_Company Code</name></content-group></content-groups><po-method>prompt</po-method><invoice-matching-level>3-way</invoice-matching-level></supplier>
Any ideas?
For that task your content in the <param> must be wrapped to the <![CDATA[ .. ]]>. Otherwise it becomes as a part of the root XML and loses it purpose to be the relaxed data for the XPath result.
I've been tasked with creating a new flow and for some reason I can't access the data that is coming in from the 'IN' Queue. I'm using MessageBrokerToolkit 7.0.0.1 in windows. The test messages are the same ones that work in production.
CREATE COMPUTE MODULE FLOW_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
DECLARE TMP ROW PASSTHRU('SELECT RAWTOHEX(UTL_RAW.CAST_TO_RAW(DBMS_OBFUSCATION_TOOLKIT.md5(INPUT_STRING => CURRENT_TIMESTAMP)))UNIQUE_ID FROM DUAL');
DECLARE blobMSG BLOB InputRoot.BLOB.BLOB;
DECLARE MSG CHARACTER CAST(blobMSG AS CHARACTER CCSID InputRoot.MQMD.CodedCharSetId ENCODING InputRoot.MQMD.Encoding);
DECLARE TITLE CHAR InputRoot.XML.Request."MessageID";
PASSTHRU(
'INSERT INTO PA0101.DEBUG_TABLE VALUES(?,?,?)',
TMP.UNIQUE_ID,
TITLE,
MSG,
);
RETURN TRUE;
END;
The DEBUG_TABLE rows come out like:
(pipe delimited)
F69A159|||
11C7EBF|||
1077ADD|||
Here is a sample message:
<Request>
<MessageID>a1f5298a-e339-423b-ac9a-4654cb46e965</MessageID>
<SendResponse>false</SendResponse>
<BasicElements>
<FeedType>Realtime</FeedType>
<MsgDT>08/09/2015</MsgDt>
<Category>Action</Category>
<PriorityCd>1</PriorityCd>
<SubjectTx>This is important</SubjectTx>
<DetailTx>[lots of html]</DetailTx>
</BasicElements>
</Request>
When I try to run command line utils on the server I usually get:
<command>
ld.so.1: <command>: fatal: libjvm.so: open failed: No such file or directory
Killed
The code doesn't produce any warnings and the .bar file builds + deploys so I am at a loss for what could be going wrong.
Most likely you are not using the message domain set on the input node in your ESQL.
You cannot use both the XML and the BLOB domain at the same time, the input message will be parsed in one or the other domain, as configured on the input node (or ResetContentDescriptor nodes in your flow).
So either InputRoot.BLOB or InputRoot.XML will be NULL. And I think that you are actually using the XMLNSC domain in your input node and the messsage body parsed in that domain can be accessed under InputRoot.XMLNSC.
In case you need the message body as BLOB and parsed as XML in the same flow, you should set the message domain as BLOB in the input node and parse the message latter in the flow by using the ResetContentDescriptor node, or by using the PARSE option of the CREATE in ESQL:
http://www-01.ibm.com/support/knowledgecenter/api/content/nl/en-us/SSKM8N_8.0.0/com.ibm.etools.mft.doc/ak04950_.htm