Karl
Karl

Reputation: 143

Attribute of a node whose child has attributes of certain values in Xpath

I'm trying to get the name of an attribute of a node which has a child node with 2 attributes which needs to match. It sounds very weird when I write it, but I suppose it shouldn't be to hard.

I'm using XLST to solve this with this code.

<xsl:template match="/">
<xsl:apply-templates  select="/parent[child[@A>10 and B='something']]/@NAME"/>

</xsl:template>
<xsl:template match="//@NAME">
    <p><xsl:value-of select="concat(., ' ')"/></p>
 </xsl:template>
</xsl:stylesheet> 

But unfortunately I cant make it work. Been trying different methods for far too long now for this problem.

The XLS looks like this:

<parent NAME="a name">
 <child A='999' B='something'>
 </child>
</parent>

<parent NAME="a name2">
 <child A='1' B='something'>
 </child>
</parent>

Thanks!

Upvotes: 1

Views: 52

Answers (2)

Tim C
Tim C

Reputation: 70618

You are not actually far off in your first expression, but it should be this..

 <xsl:apply-templates select="//parent[child[@A>10 and @B='something']]/@NAME"/>

Your current expression started with /parent which will only select parent if it is the root element of the XML. An XML document can only have a single root element, and as your XML snippet shows more than one parent, then this suggests they have a parent element that contains them.

Doing //parent though which select parent elements wherever they are in the XML.

Additionally your expression selected B (for an element) and not @B for an attribute.

So, your full XSLT would look like this

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
  <xsl:apply-templates select="//parent[child[@A>10 and @B='something']]/@NAME"/>
</xsl:template>

<xsl:template match="@NAME">
    <p><xsl:value-of select="concat(., ' ')"/></p>
 </xsl:template>
</xsl:stylesheet> 

Note there is no need to use // in the template match for @NAME.

Upvotes: 2

eLRuLL
eLRuLL

Reputation: 18799

This will get you all the names of the attributes of parent

'name(//parent[./child[@A and @B]]/@*)'

if you only want the first one (or nth attribute) just add the index in order, like this:

'name(//parent[./child[@A and @A]]/@*[1])'

Upvotes: 1

Related Questions