Jitendra Kumar
Jitendra Kumar

Reputation: 181

XPATH to select parent node along with child node

I have below xml file wherein I want to select hostname,instance name, instance type using XPATH

<root>
<hosts>
    <host id="11">
        <name>ABC</name>
        <instances>
            <instance id="11-1">
                <name>raj</name>
                <type>linux</type>
                <date>2017</date>
            </instance>
            <instance id="11-2">
                <name>raj1</name>
                <type>linux</type>
                <date>2017</date>
            </instance>
        </instances>
    </host>
    <host id="12">
        <name>XYZ</name>
        <instances>
            <instance id="12-1">
                <name>rahul</name>
                <type>solaris</type>
                <date>2017</date>
            </instance>
        </instances>
    </host>
</hosts>
</root>

I have tried below XPATH which is selecting instance name and type but not sure how to print host name along with instance name and type.

//hosts/host/instances/instance/*[self::name or self:: type]/text()

It selects the below result.

    raj
    linux
    raj1
    linux
    rahul
    solaris

However, I want output like below which has host name included

    ABC
    raj
    linux
    raj1
    linux
    XYZ
    rahul
    solaris

Upvotes: 1

Views: 2510

Answers (3)

Pradeep Prasad
Pradeep Prasad

Reputation: 11

You can achieve your desired result by using any one of below solution -

Solution - 1(Full Path) - you can skip root:

/root/hosts/host/name[text()]|/root/hosts/host/instances/instance/*[self::name or self::type]

Solution - 2(Full Path) with separate query for each result:

/root/hosts/host/name[text()] |/root/hosts/host/instances/instance/name[text()]|/root/hosts/host/instances/instance/type[text()]

Solution - 3(Node Path)

//host/name[text()]|//instance/*[self::name | self::type]

Solution - 4(Node Path)

//host/[self::name]|//instance/[self::name | self::type]

Hope above is helpful.

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295272

The following (using the | operator to combine the sets of elements selected by any of three queries) will do:

  //hosts/host[./instances/instance/name or ./instances/instance/type]/name/text()
| //hosts/host/instances/instance/name/text()
| //hosts/host/instances/instance/type/text()

Upvotes: 2

Andersson
Andersson

Reputation: 52665

If you want to include output for hostname also, try below:

//hosts/host//*[self::name or self:: type]/text()

Upvotes: 1

Related Questions