1
votes

Given an XML document like:

<SESSION NAME ="TEST" REUSABLE ="NO" SORTORDER ="Binary" VERSIONNUMBER ="1">
    <SESSIONEXTENSION DSQINSTNAME ="TEST_SQ" DSQINSTTYPE ="Source Qualifier" NAME ="Relational Reader" SINSTANCENAME ="TEST_SQ" SUBTYPE ="Relational Reader" TRANSFORMATIONTYPE ="Source Definition" TYPE ="READER"/>
    <SESSIONEXTENSION DSQINSTNAME ="TEST_TG" DSQINSTTYPE ="Source Qualifier" NAME ="Relational Reader" SINSTANCENAME ="TEST_TG" SUBTYPE ="Relational Reader" TRANSFORMATIONTYPE ="Source Definition" TYPE ="WRITER"/>
    <ATTRIBUTE NAME ="General Options" VALUE =""/>
</SESSION>

I wish to extract the NAME attribute of the SESSION element for SESSION elements for which all of the following are true:

  • the child SESSIONEXTENSION element's TYPE attribute value equals "READER",
  • the child ATTRIBUTE element's NAME attribute value equals "General Options" and
  • the child ATTRIBUTE element's VALUE attribute value equals "".

The XPath expression

/SESSION/SESSIONEXTENSION[@TYPE='READER']

returns a SESSION element containing the sought NAME attribute value.

However my attempt at an XPath expression specifying all three of the above list of SESSION element requirements

 /SESSION/SESSIONEXTENSION[@TYPE='READER']/ATTRIBUTE[@NAME="General Options" and VALUE =""]

is not working as expected.

How can I state multiple conditions in an XPath expression where the conditions are for separate children (SESSIONEXTENSION, ATTRIBUTE) of a parent element (SESSION)?

2
Try using @VALUE=... instead of VALUE=...Peter B
Possible duplicate of XPath with multiple conditionsBrian Agnew
/SESSION[SESSIONEXTENSION[@TYPE='READER'] and ATTRIBUTE[@NAME="General Options" and @VALUE =""]]splash58

2 Answers

2
votes

The following XPath returns the NAME of SESSION elements for which the ATTRIBUTE NAME is "General Options", the ATTRIBUTE VALUEis "" and the SESSIONEXTENSION TYPEis "READER":

//SESSION[ATTRIBUTE[@NAME='General Options'][@VALUE='']][SESSIONEXTENSION[@TYPE='READER']]/@NAME

basically structure of this path is the following:

// tag[child1[condition1][condition2]][child[condition3]]/@attr

or you can update it to this:

// tag[child1[condition1 and condition2] and child[condition3]]/@attr

To exclude items by a condition use pattern: [not(condition)]

so not to include WRITER, use this:

//SESSION[ATTRIBUTE[@NAME='General Options'][@VALUE='']][SESSIONEXTENSION[@TYPE='READER']][not(SESSIONEXTENSION[@TYPE='WRITER'])]/@NAME
0
votes

Building upon @splash58's comment, I believe that the following XPath returns the desired value ("the name of the session when Attribute name is General Options and values ="" and sessionextension type="READER""):

string(/SESSION[SESSIONEXTENSION[@TYPE='READER'] and ATTRIBUTE[@NAME="General Options" and @VALUE =""]]/@NAME)

That XPath evaluated against the XML in the question results in:

TEST

Remove the string() wrap around the XPath to get the attribute name and value - i.e.:

/SESSION[SESSIONEXTENSION[@TYPE='READER'] and ATTRIBUTE[@NAME="General Options" and @VALUE =""]]/@NAME

which evaluates to

NAME=TEST

against the above XML.

Above XPaths tested using https://www.freeformatter.com/xpath-tester.html.