1

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)?

Leo
  • 868
  • 1
  • 13
  • 32

2 Answers2

2

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
Vitaliy Moskalyuk
  • 2,463
  • 13
  • 15
  • Hi Vitaly, Thank for your answer. If there are two childs with name SESSIONEXTENSION one with TYPE="WRITER" and I want the get the session name only if none of my sessionextension has a type="WRITER". In this case, I should not receive any result. How should I modify my xpath expression? – Leo Oct 26 '17 at 09:22
  • you should add another parameter to session, to exclude elements by condition, i'll update answer in a min – Vitaliy Moskalyuk Oct 26 '17 at 09:27
0

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.

Mark A. Fitzgerald
  • 1,249
  • 1
  • 9
  • 20