How to Extract Text Node Value From Payload Using XPath in MEL - mule

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.

Related

Customize docbook the preferred way

I'd like to add a few elements to docbook 5 and to change a few elements. The question is: what is the preferred way?
My root element looks like this:
<book xmlns="http://docbook.org/ns/docbook" version="5.0">
</book>
And I guess I should change it to
<book xmlns="http://docbook.org/ns/docbook" version="5.0-extension acme-1.0">
</book>
Or something like this. Should I change the namespace as well? I believe I should, but this gives me some trouble, as the RelaxNG grammar expects the namespace to be http://docbook.org/ns/docbook and not for example http://example.org/ns/docbook-myextension.
My .rng file looks like this:
<grammar xmlns:db="http://docbook.org/ns/docbook" xmlns="http://relaxng.org/ns/structure/1.0">
<include href="docbookxi.rng">
<!-- change things here -->
</include>
<!-- add things here -->
</grammar>

how to replace xml element value in mule

<healthcare>
<plans>
<plan1>
<planid>100</planid>
<planname>medical</planname>
<desc>medical</desc>
<offerprice>500</offerprice>
<area>texas</area>
</plan1>
<plan2>
<planid>101</planid>
<planname>dental</planname>
<desc>dental</desc>
<offerprice>1000</offerprice>
<area>texas</area>
</plan2>
</plans>
</healthcare>
<splitter evaluator="xpath" expression="/healthcare/plans" doc:name="Splitter"/>
<transformer ref="domToXml" doc:name="Transformer Reference"/>
<logger level="INFO" doc:name="Logger" message=" plans detils...#[message.payload]" />
i have input xml data as above. I want to replace offerprice value from the above xml data . I tried various ways. anyone can shed the light for my requirement in mule
in my requiremnet , hit external api based on the result value , I need to change the offerprice value in the input xml .
anyone help is highly valuable.I need this immediately in my work .please shed light
You can use XSLT to transform the XML file to another XML file (with or without the same schema). Here's a small example of how it would look in mule . . .
http://marcotello.com/mule-esb/using-the-xslt-transformer-in-mule-esb/
There are also a lot of resources for learning how to create XSLT files online / through google.
There are many ways to do it.
You can use Mule XSLT in your flow, which will change the value of offerprice from input xml and you will be getting the required Xml as output with the value you want.
Another way is to use Groovy, with XmlSlurper to parse your input Xml, replace the value, and rebuild the XML you want.
reference :- XML Mapping in Mule
and
Mule: Enriching an XML with additional information from DB
also refer
http://www.ibm.com/developerworks/library/j-pg05199/index.html
Hope this help

Select from list of xml elements with SQL Server

Let's say I have this xml -
<book>
<author>Gambardella, Matthew</author>
<title>XML Developers Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book>
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<book>
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.</description>
</book>
I need a T-SQL query to select one book at a time from this list, because I need to do some kind of processing with that before I insert it into a table.
Let's say I want to select the second element in this list and want to display it as a table.
How can I do that?
Personally, I would shred the entire XML document into a table first, and if i REALLY couldn't do set based operations to them, iterate over the table using something like a row number and a loop, or a cursor.
If you just explicitly want to access the nth member of an xml document, you can do so when you write an xpath expression. How you'd know how many elements you need to iterate over though, I'm not sure. Here's an example of grabbing the 2nd book node:
--Assumes you've assigned the XML document you provided to an XML variable called #xml
select t.c.value('author[1]', 'varchar(50)')
from #xml.nodes('/book[2]') as t(c)

Mule object to string transformer adding one extra question mark at the start of string

i am doing a Object to string conversion, but when i am doing it is adding one extra question mark at the very begin of string.
below is my flow code
<flow name="jatoSmartWriteFromFTP" doc:name="jatoSmartWriteFromFTP" processingStrategy="synchronous">
<ftp:inbound-endpoint host="delvmpllreap03.sapient.com" port="21" path="/home/jatopoc" user="jatopoc" password="jatopoc" responseTimeout="10000" doc:name="FTP" mimeType="text/xml">
<file:filename-wildcard-filter pattern="filter_data.xml"></file:filename-wildcard-filter>
</ftp:inbound-endpoint>
<logger message="#[message.payload]" level="INFO" doc:name="Logger"></logger>
<object-to-string-transformer doc:name="Object to String" mimeType="text/xml"/>
<mulexml:jaxb-xml-to-object-transformer name="XmlToPerson" jaxbContext-ref="jatoJaxbContext" returnClass="com.jato.speedwing.common.vo.JATOXML"/>
<component doc:name="Java">
<method-entry-point-resolver>
<include-entry-point method="insert"></include-entry-point>
</method-entry-point-resolver>
<spring-object bean="jatoDAO"> </spring-object>
</component>
<jms:outbound-endpoint topic="com.jato.smart.updateInfo" connector-ref="VM_Active_MQ" doc:name="JMS"/>
</flow>
below is my xml file content at ftp
<?xml version="1.0" encoding="UTF-8"?>
<code>
data
</code>
below is the string output after doing object-to-string transformer
?<?xml version="1.0" encoding="UTF-8"?>
<code>
data
</code>
now because of this extra question mark, my jaxb-xml-to-object transformer is not working..
can anybody suggest my what do here. since my task is to read a xml file from ftp > convert that file content to jaxb object(as file content is xml data).
Place a debug breakpoint on Object->String component. Debug your application and determine exactly what you are asking to convert to String (mimeType=text/XML). Mule is interpreting something in the object given and somehow producing the question mark. Some people have seen three question marks before the XML doc declaration and also other character combinations. The 3 question marks represent a byte order mark (BOM) that's a special UNICODE character dealing with endian-ness and byte order. Your case may be related to the character encoding as well. Debug the flow and identify the incoming object. Understand the operation and it's parameters.

How to use Xpath on mule.payload which contains string arrray

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