I have mule payload which contains 3 different soap request message.
How can I read the value of one of the xml tag/node present in 2nd soap request using MEL ?
e.g. message payload is as follows
[
<soap:Envelope>
<book>
<name>ABC</name>
<author>ABCD</author>
</book>
<book>
<name>WXY</name>
<author>WXYZ</author>
</book>
<soap:Envelope> ,
<soap:Envelope>
<fruit>
<name>Apple</name>
<color>Red</author>
</fruit>
<fruit>
<name>Orange</name>
<color>Orange</author>
</fruit>
<soap:Envelope> ,
<soap:Envelope>
<soap:Envelope>
]
I want to read the value of "name of all fruits" using xpath and MEL.
If the payload is an array of String containing each element the XML, you can do this:
#[xpath('xpath expression', payload[1])]
perhaps a copy and paste error in your example however
<color>Orange</author>
wont ever work
However assuming you mean the xml is something like:
<soap:Envelope>
<fruit>
<name>Apple</name>
<color>Red</color>
</fruit>
<fruit>
<name>Orange</name>
<color>Orange</color>
</fruit>
</soap:Envelope>
then you can use Mvel [xpath://fruit[1]/name/text()] to get indivdual xpath items
or [xpath://fruit/name/text()] to get all
A good site to test xpath queries are:
http://chris.photobooks.com/xml/default.htm
Related
My response data is having text in it.
I am not able to get data from any of the fields using xpath from this response.
Karate shows "xml parsing failed, response data type set to string: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 716; The entity "nbsp" was referenced, but not declared." all xpaths
(Eg: response/transaction/values/data/#name)
I need to verify the commentDisplay tag in below xml. How to proceed?/ Is there any way to remove before fetching the value using xpath?
<Response>
<RequestID>1234</RequestID>
<transaction>
<values>
<data name="firstName">Sumith</data>
<data name="lastName">Menon</data>
</values>
<commentDisplay>
<top>Please Verify IDCard</top>
<bottom/></commentDisplay>
</transaction>
</Response>
is invalid in XML, refer: https://stackoverflow.com/a/36097922/143475
But you can correct this in one step:
* xml response = response.replaceAll(' ', ' ')
I want to do field level validation in mule, i am able do the schema validation but stuck in field level validation for example first name should be string and not empty and date of birth should in be in integer format and not empty etc..
I am attaching my sample file , i know there is a component ( validation) which do such type of validation but i have many filed in XML ( here i have attached simple XML file due to security issues),which is basically called business validation.
Kindly help me how to do such type of validation in mule.
<?xml version="1.0"?>
<x:books xmlns:x="urn:books">
<book id="bk001">
<author>Writer</author>
<title>The First Book</title>
<genre>Fiction</genre>
<price>44.95</price>
<pub_date>2000-10-01</pub_date>
<review>An amazing story of nothing.</review>
</book>
<book id="bk002">
<author>Poet</author>
<title>The Poet's First Poem</title>
<genre>Poem</genre>
<price>24.95</price>
<review>Least poetic poems.</review>
</book>
</x:books>
Cheers,
Isr
Kindly refer to below link. you can use validations module i has predefined set of validations.
https://docs.mulesoft.com/mule-user-guide/v/3.7/validations-module
EX: To validate a field is not empty. use this validator module.
<validation:is-not-empty expression="#[(xpath expression goes here)/]" />
If it doesn't match your expectations then using Xpath parse the respective fields and use an expression component to do all these validations.
Thanks!
I am really new to SQL Server and stored procedures to begin with. I need to be able to parse an incoming XML file for a specific element's value and compare/save it later in the procedure.
I have a few things stacked against me. One the Element I need is buried deeply inside the document. I have had no luck in searching for it by name using methods similar to this:
select CurrentBOD = c.value('(local-name(.))[1]', 'VARCHAR(MAX)'),
c.value('(.)[1]', 'VARCHAR(MAX)') from #xml.nodes('PutMessage/payload/content/AcknowledgePartsOrder/ApplicationArea/BODId') as BODtable(c)
It always returns null.
So, I am trying something similar to this:
declare #BODtable TABLE(FieldName VARCHAR(MAX),
FieldValue VARCHAR(MAX))
SELECT
FieldName = nodes.value('local-name(.)', 'varchar(50)'),
FieldValue = nodes.value('(.)[1]', 'varchar(50)')
FROM
#xml.nodes('//*') AS BODtable(nodes)
declare #CurrentBOD VARCHAR(36)
set #CurrentBOD = ''
SET #CurrentBOD = (SELECT FieldValue from #BODtable WHERE FieldName = 'BODId')
This provides me the list of node names and values correctly (I test this in a query and BODtable has all elements listed with the correct values), but when I set #CurrentBOD it comes up null.
Am I missing an easier way to do this? Am I messing these two approaches up somehow?
Here is a part of the xml I am parsing for reference:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<payloadManifest xmlns="???">
<c contentID="Content0" namespaceURI="???" element="AcknowledgePartsOrder" version="4.0" />
</payloadManifest>
<wsa:Action>http://www.starstandards.org/webservices/2005/10/transport/operations/PutMessage</wsa:Action>
<wsa:MessageID>uuid:df8c66af-f364-4b8f-81d8-06150da14428</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>???</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-bd91e76f-c212-4555-9b23-f66f839672bd">
<wsu:Created>2013-01-03T21:52:48Z</wsu:Created>
<wsu:Expires>2013-01-03T21:53:48Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="???" wsu:Id="???">
<wsse:Username>???</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">???</wsse:Password>
<wsse:Nonce>???</wsse:Nonce>
<wsu:Created>2013-01-03T21:52:48Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<PutMessage xmlns="??????">
<payload>
<content id="???">
<AcknowledgePartsOrder xmlns="???" xmlns:xsi="???" xsi:schemaLocation="??? ???" revision="???" release="???" environment="???n" lang="en-US" bodVersion="???">
<ApplicationArea>
<Sender>
<Component>???</Component>
<Task>???</Task>
<ReferenceId>???</ReferenceId>
<CreatorNameCode>???</CreatorNameCode>
<SenderNameCode>???</SenderNameCode>
<DealerNumber>???</DealerNumber>
<PartyId>???</PartyId>
<LocationId />
<ServiceId />
</Sender>
<CreationDateTime>2013-01-03T21:52:47</CreationDateTime>
<BODId>71498800-c098-4885-9ddc-f58aae0e5e1a</BODId>
<Destination>
<DestinationNameCode>???</DestinationNameCode>
You need to respect the XML namespaces!
First of all, your target XML node <BODId> is inside the <soap:Envelope> and <soap:Body> tags - both need to be included in your selection.
Secondly, both the <PutMessage> as well as the <AcknowledgePartsOrder> nodes appear to have default XML namespaces (those xmlns=.... without a prefix) - and those must be respected when you select your data using XPath.
So assuming that <PutMessage xmlns="urn:pm"> and <AcknowledgePartsOrder xmlns="urn:apo"> (those are just guesses on my part - replace with the actual XML namespaces that you haven't shown use here), you should be able to use this XPath to get what you're looking for:
;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap,
'urn:pm' AS ns, 'urn:apo' AS apo)
SELECT
XC.value('(apo:BODId)[1]', 'varchar(100)')
FROM
#YourXmlVariable.nodes('/soap:Envelope/soap:Body/ns:PutMessage/ns:payload/ns:content/apo:AcknowledgePartsOrder/apo:ApplicationArea') AS XT(XC)
This does return the expected value (71498800-c098-4885-9ddc-f58aae0e5e1a) in my case.
I want to extract some text values from an message's XML payload so that I can use them in a jdbc query.
Given the test XML file below I want to obtain the string value of first book's author text node.
Something like:
INSERT INTO books VALUES (#[xpath('/catalog/book[0]/author/text()')])
To test the expression I am just using a logger but can't seem to get it to extract correctly.
<logger message="#[xpath('/catalog/book[0]/author/text()')]" level="DEBUG" doc:name="Logger"/>
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
</book>
</catalog>
Here is the correct MEL expression:
#[xpath('/catalog/book[1]/author/text()').text]
Note in XPath, the first node is 1 not 0.
David's answer worked fine except for one thing. For me, .text didn't work. I had to use .wholeText. This is probably because I'm using a xerces implementation somewhere in my work project.
I am being returned some XML from a web service. Basically, the xml looks like this:
<response>
<data>
More XML here but the it's escaped by XML entities
</data>
</response>
so, as you can see, I have xml that is valid, but the stuff inside data tag is escaped with XML entities. what's the best (most efficient) way for me to feed this into the parser?
What I am doing right now is, when I get the data from web service, I convert it into NSString....then replace the "XML escaped entities" with real ones.....then convert it back into NSData...then feed it into the parser. This doesn't seem like a very good solution so I was wondering if there's a better way to do it?
Thanks.
Alright, here's the xml that I am getting:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><ActivityId CorrelationId="d39007b5-ee69-41c7-a61d-831b456f9ea3" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">aa88d1cd-253c-48d1-abeb-62a880bea806</ActivityId></s:Header><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><LoginResponse xmlns="http://MSS"><LoginResult><LoginInformation>
<User>
<UserID>612</UserID>
<UserName>Demo User</UserName>
<Email>mssdev#mss-mail.com</Email>
<CompanyID>17034</CompanyID>
<CompanyName>PlanET Demonstration Agency</CompanyName>
</User>
</LoginInformation></LoginResult></LoginResponse></s:Body></s:Envelope>
As you can see, everything in is escaped.
That's kind of horrifying. Why don't you just take the contents of that tag (e.g. the data with the entities) and just pass that through another NSXMLParser? The first parser will have decoded the entities, and the second parser will be presented with the decoded version of the contents of that tag.