XPATH to get multiple values - xpath

<values>
<value index="1">
<token>
<secret>
<client_key>
</value>
<value index="2">
<token>
<secret>
<client_key>
</value>
<value index="3">
<token>
<secret>
<client_key>
</value>
</values>
Can anyone please help me with the xpath to get the token value from all the indexes . The no of indexes will vary each time and not a constant.possible values are (1 or >1)

Searches for tokens inside values that has attribute index
//value[#index]/token

Related

Can i use complex condition using XPath in Filter Mediator WSO2?

I have a condition written in SQL Language that i would like to use it in Filter Mediator XPath but it didn't work and it give me an error .
NB : I got variable value from JSON payload .
Actual SQL Condition
(!ISNULL(a) && a== 2 && b== 1) || c== 5
Expected XPath Condition
(//a=2 AND //b=1) OR //c=5
Try the following.
<filter xpath="boolean(//a/text() = '1' and //b/text() = '2') or //c/text() = '3'">
<then>
<log>
<property value="===== TRUE" name="MSG"/>
</log>
</then>
<else>
<log>
<property value="===== FALSE" name="MSG"/>
</log>
</else>
</filter>

XPath 2 expressions interfering with each other

I have a XML like this:
<Values>
<Value AttributeID="asset.extension">pdf</Value>
<Value AttributeID="asset.size">10326</Value>
<Value AttributeID="ATTR_AssetPush_Webshop">1</Value>
<Value AttributeID="asset.format">PDF (Portable Document Format application)</Value>
<Value AttributeID="asset.mime-type">application/pdf</Value>
<Value AttributeID="asset.filename">filename.pdf</Value>
<Value AttributeID="asset.uploaded">2018-01-10 17:05:39</Value>
<Value AttributeID="ATTR_Verwendungsort" Derived="true">WebShop,</Value>
</Values>
I have 2 (or more) XPath-expressions like this:
<xsl:template match="/STEP-ProductInformation/Assets/Asset/Values/Value[not(#AttributeID='asset.mime-type')]" />
<xsl:template match="/STEP-ProductInformation/Assets/Asset/Values/Value[not(#AttributeID='asset.size')]" />
For some reason though, If I have 2 of them together, all information are being stripped. If I use only 1 expressoin, I get my desired output. Can't I use 2 expressions like this?
I also tried combining them like this:
<xsl:template match="/STEP-ProductInformation/Assets/Asset/Values/Value[not(#AttributeID='asset.mime-type') and (#AttributeID='asset.size')]" />
But that didn't do it, either.
The desired output would be like this:
<Values>
<Value AttributeID="asset.size">10326</Value>
<Value AttributeID="asset.mime-type">application/pdf</Value>
</Values>
I think in XSLT 2/3 you could express it as
<xsl:template match="Values/Value[not(#AttributeID = ('asset.mime-type', 'asset.size'))]"/>
In XSLT/XPath 1.0 you would need Values/Value[not(#AttributeID = 'asset.mime-type' or #AttributeID = 'asset.size')].
<xsl:template match="/STEP-ProductInformation/Assets/Asset/Values
/Value[not(#AttributeID='asset.mime-type')]" />
<xsl:template match="/STEP-ProductInformation/Assets/Asset/Values
/Value[not(#AttributeID='asset.size')]" />
This is a logical error -- has nothing to do with XPath.
It is like saying:
From all days of the week I will work only on Mondays
From the days selected above I will work only on Tuesdays
The first statement above selects only Mondays. The 2nd statement selects all Tuesdays from these Mondays -- that is the empty set.
A correct statement:
From all days of the week I will work only on Mondays or Tuesdays

XPath with multiple child node conditions

I'm trying to find a XPath expression, to get an elment with multiple conditions on child nodes.
Which XPath can I use to get the ball element with ART_NR = 146334 and FABRICATOR = SPALDING?
The corresponding XML:
<xml>
<ball sellCode="ABC7001" type="basket ball">
<detail>
<type>INFO</type>
<values>
<type>NUMERIC</type>
<value>146334</value>
<id>ART_NR</id>
</values>
<values>
<type>NUMERIC</type>
<value>39.99</value>
<id>PRICE</id>
</values>
<values>
<type>STRING</type>
<value>SPALDING</value>
<id>FABRICATOR</id>
</values>
<values>
</detail>
<detail>
<type>MOD</type>
...
</detail>
</ball>
<ball sellCode="ABC34564" type="golf ball">
...
</xml>
Both the following XPath expressions should work:
/xml/ball[detail[values[id='ART_NR'][value=146334]]
[values[id='FABRICATOR'][value='SPALDING']]]
/xml/ball[detail[values[id='ART_NR' and value=146334]
and values[id='FABRICATOR' and value='SPALDING']]]

How to extract a node value from an xml in Mule

This is my source xml sample.
<?xml version="1.0" encoding="UTF-8"?>
<XML>
<Meta>
<Status>Success</Status>
<Debug></Debug>
</Meta>
<Result>
<Surveys>
<element id='0'>
<responses>6</responses>
<SurveyType>SS</SurveyType>
<SurveyID>SV_01C7i5l62dnKTel</SurveyID>
<SurveyName>Georgia Dome GS</SurveyName>
<SurveyDescription>Georgia Dome</SurveyDescription>
<SurveyOwnerID>UR_8IZEh6bVlQaF41L</SurveyOwnerID>
<DivisionID>DV_2cmHYrtm8C93T6J</DivisionID>
<SurveyStatus>Active</SurveyStatus>
<SurveyStartDate>0000-00-00 00:00:00</SurveyStartDate>
<SurveyExpirationDate>0000-00-00 00:00:00</SurveyExpirationDate>
<SurveyCreationDate>2014-06-18 15:14:48</SurveyCreationDate>
<CreatorID>UR_8IZEh6bVlQaF41L</CreatorID>
<LastModified>2014-10-24 14:01:23</LastModified>
<LastActivated>2014-06-24 09:39:23</LastActivated>
<GroupName>Analytics</GroupName>
<GroupID>GR_3kMZEX6m1IqqSjP</GroupID>
<UserLastName>Parrott-Sheffer</UserLastName>
<UserFirstName>Brandon</UserFirstName>
</element>
I would like to print a list of all the value that come in the tag - <SurveyID>.
The following is my Mule flow:
</flow>
</flow>
<flow name="testFlow1" doc:name="testFlow1">
<file:inbound-endpoint path="C:\Data\Mule\deploy\out" responseTimeout="10000" doc:name="File"/>
<file:file-to-string-transformer doc:name="File to String"/>
<logger message="*********First Message - ********* #[message.payload.toString()]" level="ERROR" doc:name="Logger"/>
<foreach collection="#[xpath('//XML/Result/Surveys/element')]" doc:name="For Each">
<set-variable doc:name="Variable" value="#[xpath('SurveyID/text()').text]" variableName="id"/>
<logger level="INFO" message="********* The ID is - #[flowVars['id']]" doc:name="Logger"/>
</foreach>
</flow>
But the result I see on the console is -
INFO 2015-01-20 17:03:35,527 [[REST-API].testFlow1.stage1.02]
org.mule.transformer.simple.AddFlowVariableTransformer: Variable with
key "id", not found on message using
"#[xpath('//SurveyID/text()').text]".Since the value was marked optional,
nothing was set on the message for this variable
INFO 2015-01-2017:03:35,527 [[REST-API].testFlow1.stage1.02] org.mule.api.processor.LoggerMessageProcessor: null
I am getting this xml from a third party and I noticed it does not have any namespace information. Can you please help correct my xpath and display the values.
I am using Mule studio 3.5
First of all I need to say your XML is not valid as it doesn't have ending tags as mentioned by Victor
Anyways,if you make it correct then, You can easily get the value of all SurveyID nodes using XPATH3 and splitter
<flow name="testFlow">
<http:listener config-ref="HTTP_InboundRequest" path="/test" doc:name="HTTP"/>
<splitter expression="#[xpath3('//XML/Result/Surveys/element',message.payload,'NODESET')]" doc:name="Splitter"/>
<logger level="INFO" message="#[xpath3('SurveyID')]" doc:name="Logger"/>
</flow>
It will successfully print all the values of SurveyID
I am not familiar with Mule, only with XPath. But
SurveyID/text()
as in
<set-variable doc:name="Variable" value="#[xpath('SurveyID/text()').text]" variableName="id"/>
would be more logical in my opinion, because inside this for loop, it does not make sense to use an expression that starts with //. Let me know if it works.
You should also slightly modifiy the other XPath expression, also removing the //, then the whole should be
<foreach collection="#[xpath('/XML/Result/Surveys/element')]" doc:name="For Each">
<set-variable doc:name="Variable" value="#[xpath('SurveyID/text()').text]" variableName="id"/>
<logger level="INFO" message="#[flowVars['id']]" doc:name="Logger"/>
</foreach>
Finally, I'm not sure why you select text nodes and then write .text. To me, it seems like you are doing the same thing twice. What does
#[xpath('SurveyID').text]
do?
The xpaths you are using should work, although they could be optimized.
The sample xml looks ok too except for the fact that lacks the closing of three elements:
</Surveys>
</Result>
</XML>
My guess is that sometimes it fails for your depending on the input. I do recommend to put a
<logger message="#[message.payload]" level="ERROR" />
right before the foreach and inside the foreach.

XPath matching the element with maximum value of an attribute

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
<user number="0775547857">
<step stepnumber="1">complete</step>
<step stepnumber="2">complete</step>
<step stepnumber="3">complete</step>
</user>
<user number="0775543754">
<step stepnumber="1">complete</step>
<step stepnumber="2">complete</step>
</user>
<user number="0777743059">
<step stepnumber="1">complete</step>
</user>
</users>
Given a number, I want to find the maximum stepnumber in the list of steps.
What i've got so far is //user[#number='0775547857']/step[#stepnumber]
And i think I have to use the fn:max function but I am having trouble on how to use the max function passing the list of step numbers.
Example : If i give number 0775547857, the maximum step number is 3 and for 0775543754 it is 2 and so on.
Thanx a lot in advance.
Is this correct?
//user[#number='0772243950']/step[fn:max((#stepnumber))]
The max() function is defined only in XPath 2.0 and above.
An XPath 2.0 expression that finds the maximum stepnumber of the step children of a user that has a number attribute with value $pNum is:
max(/*/user[#number=$pNum]/step/#stepnumber/xs:integer(.))
Substituting $pnum with 0775547857 and evaluating this XPath 2.0 expression on the following XML document:
<users>
<user number="0775547857">
<step stepnumber="1">complete</step>
<step stepnumber="11">complete</step>
<step stepnumber="2">complete</step>
<step stepnumber="3">complete</step>
</user>
<user number="0775543754">
<step stepnumber="1">complete</step>
<step stepnumber="2">complete</step>
</user>
<user number="0777743059">
<step stepnumber="1">complete</step>
</user>
</users>
produces the wanted, correct result:
11
Do note: using the xs:integer(.) above is necessary if we want to find the maximum of values as integers. Without it the maximum will be found on the values as strings and 3 will be bigger than 11.
In XPath 1.0 the following XPath expression returns the wanted maximum value:
/*/user[#number=$pNum]/step
[not(#stepnumber
<
../step/#stepnumber
)
]
/#stepnumber
Try this:
fn:max(//user[#number='0775547857']/step[#stepnumber])

Resources