codereviewanskquestions
codereviewanskquestions

Reputation: 13998

XML XPath question

 <categories>
<member>
    <name> Ants </name>
    <size> 8 </size>
    <submember>
        <structure>
            <name>Acrobat Ants </name>
            <size>Slightly over 1/8" </size>
            <color>Tan, red with heart shaped abdomen </color>
            <habitat>Inside moist wood</habitat>
            <found>Throughout the US</found>
            <desc></desc>
            <productLink> </productLink>
        </structure>

        <structure>
            <name>Argentine Ant </name>
            <size>About 1/16" </size>
            <color>Light to dark brown </color>
            <habitat>Shallow areas with moist soil</habitat>
            <origin>Argentina and Brazil</origin>
            <desc></desc>
            <productLink></productLink>
        </structure>    

        <structure>
            <name>Carpenter Ants </name>
            <size>1/4-1/2" </size>
            <color>Varies</color>
            <Habitat>Inside decayed or moist wood</Habitat>
            <Found>Throughout the US</Found>
            <desc>C</desc>
            <productLink></productLink>
        </structure>
     </submember>
 </member>
 </categories>

Let's say I have a XML file like this (the actual xml is much longer than this) then how do I get "Ants" structure using xpath?

Upvotes: 1

Views: 155

Answers (3)

Jeff Mercado
Jeff Mercado

Reputation: 134571

I'm guessing that you want the member which contains Ants as the Name. This should be enough:

/categories/member[name=' Ants ']

Note the quotes include the spaces needed for the name. Whitespace is important in XML so the spaces around Ants are part of the content as well. Otherwise you could normalize the spaces first which effectively trims the excessive whitespace first before comparing.

/categories/member[normalize-space(name)='Ants']

As Alejandro points out, you might want the structure descendants under the Ants element. Then you'd need to dig a bit further.

/categories/member[normalize-space(name)='Ants']/submember/structure

Upvotes: 4

Wayne
Wayne

Reputation: 60424

Here are a few extensions to @Jeff's (good) answer. This targets all <structure> elements below the <member> whose name contains Ants (accounting for leading/trailing spaces):

/categories/member[normalize-space(name)='Ants']/submember/structure

Or just the first one:

/categories/member[normalize-space(name)='Ants']/submember/structure[1]

Just Carpenter Ants:

/categories/member[normalize-space(name)='Ants']/submember/structure[normalize-space(name)='Carpenter Ants']

And so on...

You should try to generalize these for your own uses.

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243569

Let's say I have a XML file like this (the actual xml is much longer than this) then how do I get "Ants" structure using xpath?

I guess that you want to select any structure with child name, whose string value contains the string "Ants".

Use:

  /*/*/*/structure[contains(name, 'Ants')]

This selects any structure element that has a child name that contains the string "Ants" and that (the sructure element) is a child of any element that is a child of any element that is a child of the top element of the XML document.

Or, use:

  /*/*/*/structure[contains(concat(name,' '), ' Ants ')]

This selects a structure element that satidfy all requirements as in the previous expression with the exception that its name child must contain an "Ants" preceded by a space and either followed by a space or being the ending substring of the complete string value of name.

Upvotes: 1

Related Questions