user3735178
user3735178

Reputation: 149

xpath select all attributes ending with foo?

Is it possible with XPATH/XSLT 1.0 to select all attributes ending with "Foo"?

I'm writing some XSLT to get the list of all values of all attributes for all "InterestingElement"s where the attribute name ends with "Foo".

Actually I also want to filter out those where the value is empty ""

I tried specifying a stylesheet for XSLT 2.0 but got xsl:version: only 1.0 features are supported:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:fo="http://www.w3.org/1999/XSL/Format"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:fn="http://www.w3.org/2005/xpath-functions"
            xmlns:xdt="http://www.w3.org/2005/xpath-datatypes">

So far I have:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:for-each select="//InterestingElement">
<xsl:value-of select="__what goes here?__"/><xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:text>end</xsl:text>
</xsl:template>
</xsl:stylesheet>

And here's some sample XML:

<?xml version="1.0"?>
<root>
  <Other Name="Bob"/>
  <InterestingElements>
    <InterestingElement AttrFoo="want this"
                        Attr2Foo="this too"
                        Blah="not this"
                        NotThisFoo=""/>
  </InterestingElements>
</root>

Upvotes: 2

Views: 1126

Answers (2)

AntonH
AntonH

Reputation: 6437

XPath 1.0 Solution

string-join and ends-with are XPath 2.0. For 1.0, you can use the following, which returns all the values separated by space:

<xsl:for-each select="//InterestingElement/@*['Foo' = substring(name(.), string-length(name(.)) - string-length('Foo') +1) and . != '']">
  <xsl:value-of select="." /><xsl:text> </xsl:text>
</xsl:for-each>

To get the matching attribute names instead of values, change the select to select="name(.)"

Based on kjhughes answer and this SO answer.

Upvotes: 3

kjhughes
kjhughes

Reputation: 111726

XPath 2.0 Solution

XPath 2.0 alone can solve this; in XSLT 2.0, no xsl:for-each is needed -- just xsl:value-of.

This XPath,

string-join(//InterestingElement/@*[ends-with(name(.), 'Foo') and . != ''], ' ')

will return a space-separated list of the (non-empty) values of all InterestingElement attributes whose name ends with Foo.

Upvotes: 4

Related Questions