tortoise
tortoise

Reputation: 613

Xpath expression to extract an object/part of XML from an XML

I am trying to set a variable by extracting a part of payload XML. But this xpath expression works only for simple child nodes but not for elements which have children.

Expected: Need to log all the child nodes of 'cde' element of below request XML. Both approaches are not working.

<logger level="INFO" message=" approach1: #[xpath://*[local-name()='abc']/*[local-name()='cde']]" />
<logger level="INFO" message=" approach2: #[xpath('//abc/cde/node()').text]" />

Input XML:

<abc>
  <def>def123</def>
  <cde>
    <ghf>ghf123</ghf>
  </cde>
</abc>

Is there any other approach to extract part of an xml except using XSLT? Can groovy evaluator be used with that ?

EDIT: Expected: All the contents of cde element are required.

Upvotes: 0

Views: 2098

Answers (3)

user1760178
user1760178

Reputation: 6697

If you want to getan Element completely using XPATH then use the follwoing

<logger level="INFO" message=" approach1: #[xpath('//abd/cde')]"/>

This will give you

<cde>
   <ghf>ghf123</ghf>
 </cde>

Note: This above MEL will give the element as a org.dom4j.tree.DefaultElement object. You can try converting it to object using JAXB if required.

If you are looking for all the child element so cde the try the following XPATH.

#[xpath('//abd/cde/*')]"

Note: This will give you an output of an array of org.dom4j.tree.DefaultElement objects, one for each immediate child element.

Hope this helps.

Upvotes: 0

Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

I don't think there is an issue to extract the value.

You can use #[xpath://.[xpath:local-name()='abc']/*[xpath:local-name()='cde']/*[xpath:local-name()='ghf']] for extracting the value of ghf.

Here is a simple example to extract the value of <ghf>. This will work:

<flow name="Flotttt" doc:name="Flow1WithoutUsingNameSpaceManager">
  <file:inbound-endpoint responseTimeout="10000" connector-ref="File_Input" doc:name="File" path="E:\backup\test">
    <file:filename-regex-filter pattern="aa.xml" caseSensitive="false" />
  </file:inbound-endpoint>
  <logger message="Trying to process : #[xpath://.[xpath:local-name()='abc']/*[xpath:local-name()='cde']/*[xpath:local-name()='ghf']]" level="INFO" doc:name="Logger" />
  <choice doc:name="Choice">
    <when expression="#[xpath://.[xpath:local-name()='abc']/*[xpath:local-name()='cde']/*[xpath:local-name()='ghf'] ='ghf123']">
      <processor-chain doc:name="Processor Chain">
        <logger message="[WithoutUsingNameSpaceManager] MATCH" level="INFO" doc:name="Logger" />
      </processor-chain>
    </when>
    <otherwise>
      <processor-chain doc:name="Processor Chain">
        <logger message="NO MATCH" level="INFO" doc:name="Logger" />
      </processor-chain>
    </otherwise>
  </choice>
</flow>

You will get the value of <ghf> in logger... You can log all the child nodes of 'cde' element using this approach.

Upvotes: 0

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22647

I am not familiar with Mule, but the XPath expression for

all the child nodes of 'cde' element

is, in case by "all the child nodes" you meant all element child nodes:

"//cde/*"

Else, if you really meant any kind of node:

"//cde/node()"

Upvotes: 2

Related Questions