Select Xpath element value based on value of another element - xpath

I am trying to capture a value using XPath based on value of a different field.
Example XML:
<?xml version="1.0" encoding="UTF-8" ?>
<employees>
<employee>
<id>1</id>
<firstName>Tom</firstName>
<lastName>Cruise</lastName>
<photo>https://jsonformatter.org/img/tom-cruise.jpg</photo>
</employee>
<employee>
<id>2</id>
<firstName>Maria</firstName>
<lastName>Sharapova</lastName>
<photo>https://jsonformatter.org/img/Maria-Sharapova.jpg</photo>
</employee>
<employee>
<id>3</id>
<firstName>Robert</firstName>
<lastName>Downey Jr.</lastName>
<photo>https://jsonformatter.org/img/Robert-Downey-Jr.jpg</photo>
</employee>
</employees>
I am trying to get Xpath expression for value in the firstName field, when id value is 3.

You can locate parent node based on the known child node and then find the desired child node of that parent, as following:
//employee[./id='3']/firstName
the expression above will give the desired firstName node itself.
To retrieve it's text value this can be used:
//employee[./id='3']/firstName/text()

Related

Xpath queries based on given node

I have a this xml:
<?xml version="1.0"?>
<catalog>
<car>
<id>0</id>
<color>green</color>
<color>red</color>
<color>yellow</color>
<vip>
<user>Trump</user>
<user>Obama</user>
<user>Merkel</user>
</vip>
</car>
<car>
<id>1</id>
<color>green</color>
<color>red</color>
<color>yellow</color>
<vip>
<user>Putinski</user>
<user>Orlovski</user>
<user>Idiotski</user>
</vip>
</car>
<car>
<id>2</id>
<color>green</color>
<color>red</color>
<color>yellow</color>
<vip>
<user>Clooney</user>
<user>Lopez</user>
<user>Ford</user>
</vip>
</car>
</catalog>
And I am fighting with some simple things:
a) count the "color" nodes from car id 0
b) retrieve Obama's car id
For a) I know how to identify car id 0
/catalog/car/id=0
gives me a TRUE - so this is the proof I am on the right track. But now how can I continue counting the "color" nodes based on car id 0? The solution postet here does not work, as well as the following-sibling results in an javax.xml.transformerException. Does anybody know how to solve this?
To count the color nodes in car with id = 0 you can use
count(/catalog/car[id="0"]/color)
Returns 3
To get Obama's car id:
/catalog/car[.//user="Obama"]/id/text()
Returns 0

How to find element by attribute value?

I want to find the <issue> where id = 6. How do I do it? I tried the following, but it didn't work:
<issues>
<issue>
<id>7</id>
<project id="1" name="testProject"/>
<author id="1" name="testAuthor"/>
<subject>subject</subject>
<start_date>2015-08-24</start_date>
</issue>
<issue>
<id>6</id>
<project id="2" name="testProject2"/>
<author id="2" name="testAuthor2"/>
<subject>subject2</subject>
<start_date>2015-08-24</start_date>
</issue>
</issues>
My XPath expression attempts are:
doc.xpath("//id[contains(text(), '6']")
and
doc.xpath("//issue[#id=6]")
You can simply use the following XPath expression to get the issue element having a child element where id equals 6:
//issue[id=6]
id is a child element, not an attribute so you don't use #id for this task.

Xpath conditioning in datamapper using rule

If the below XML is evaluated using datamapper to map only even numbered id's to output then the condition using xpath(Rule) is : ?
<employees>
<employee>
<id>1</id>
<name>aaa</name>
</employee>
<employee>
<id>2</id>
<name>bbb</name>
</employee>
<employee>
<id>3</id>
<name>ccc</name>
</employee>
<employee>
<id>4</id>
<name>ddd</name>
</employee>
</employees>
I tried using /employee[id mod 2 = 0]/id. It maps if the input has only one even number and fails if it has more than one even numbered id in the input.xml.
The error is
Result of xpath filling field 'id' contains two or more values!
Rules are independent to each Element Mapping configured in DM. Rules are to be created in the element mapping configuration it is intended to be used in.
For the sample xml provided, this rule should be created in Foreach 'employee' -> 'employee' element mapping.
Try this for the rule configuration
Name : {Rule Name}
Type : Boolean
Context : /employees/employee
Xpath : /matches(string(id mod 2), '0')
This creates a rule returning true if id is even and false if id is odd.
Use an if block in DM script view and check for the rule's value. if rule value is true, only then map the id.
It also worked in this way
Name : {Rule Name}
Type : String
Context : /employees/employee
Xpath : /id mod 2 = 0
and used the if condition as below :
if(input.Ruleid.equals("true")){
output.id = input.id;
output.name = input.name;
}
Is there any other way to do this without using if condition.

Linq to XML - get elements that have certain child element

Using LINQ to XML, how do I get a collection of all elements that have a named child element.
for example;
<root>
<Garage>
<Car id="001">
<Price PaymentType="Cash">$100</Price>
</Car>
<Car id="002">
<Price PaymentType="Cash">$200</Price>
</Car>
<Car id="003">
</Car>
</Garage>
</root>
this will return 2 Car elements (#1 and #2) as they have the Price element. It won't return Car #3, as it doesn't have a price element.
thanks as always
Assuming you have an XDocument object named doc with your example xml loaded into it. You could try something like this.
IEnumerable<XElement> elements = doc.Descendants("Garage").Elements().Where(e => e.Elements().Any());

XPATH Expression help needed

I have an XML file:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nodeA>
</nodeA>
<nodeB>
<nodeB></nodeB>
<nodeB></nodeB>
<nodeB></nodeB>
<nodeB></nodeB>
</nodeB>
<nodeC>
</nodeC>
</root>
I want to write an XPATH expression which will select the <nodeB> which is the parent of the other <nodeB> nodes. I tried something like
"//nodeB/nodeB/parent::nodeB"
but it also choses <nodeC> besides the one I want.
Can you please help?
thanks
mc
Try this (nodeB having a child of nodeB)
//nodeB[nodeB]

Resources