0

I am trying to get an attribute value for an elements ancestor, self and descendants. And then I want to display the unique values.

This is what I am trying.

<xsl:key name="remove" match="value" use="sortedvalues" />

<xsl:for-each select="ancestor-or-self::node()/@value[generate-id() = generate-id(key('remove',sortedvalues)[1])] | descendant-or-self::node()/@value[generate-id() = generate-id(key('remove',sortedvalues)[1])]">

            <xsl:for-each select="key('remove',sortedvalues)">
            <xsl:sort select="sortedvalues"></xsl:sort>

            </xsl:for-each>

            </xsl:for-each>

And here is the actual XML

<Root>

     <something value = “asd” </something>
    <something value = “dsa” </something>
  <Product>
    <something value = "asd"></something>
    <something value = "dsa"></something>
    <something value = "asd"></something>

    <anothernode>
    <something value = "qwe"></something>
    </anothernode>

    <anothernode2>
    <something value = "ewq"></something>
    </anothernode2>

    <something value = "ewq"></something>

<Product>

  <Product>
    <something value = "asd"></something>
    <something value = "dsa"></something>
    <something value = "asd"></something>

    <anothernode>
    <something value = "qwe"></something>
    </anothernode>

    <anothernode2>
    <something value = "ewq"></something>
    </anothernode2>

    <something value = "ewq"></something>

<Product>
</Root>

I basically wanna show

<Product>
    <values>asd <values>
    <values>dsa<values>
    <values>qwe<values>
    <values>ewq<values>
<Product>


<Product>
    <values>asd <values>
    <values>dsa<values>
    <values>qwe<values>
    <values>ewq<values>
<Product>

So I cant use // to show for each individual products so I have been using ancestor and descendant on Product

alan samuel
  • 415
  • 6
  • 28
  • So do you need to take those `asd ` child elements of the `Root` element into account? Or are you just looking for unique `@value` attributes inside of a `Product` element? – Martin Honnen May 23 '18 at 07:16
  • Both....if its outside of product i need to consider that too. – alan samuel May 23 '18 at 07:23

1 Answers1

0

If you want to get the unique value attributes by product, you will have to make a reference to the product part of the key

 <xsl:key name="values" match="@value" use="concat(generate-id(ancestor::Product), '|', .)" />

Then, for a given product, you get the distinct values like so (where $id is a variable containing the value of generate-id() for the product)

<xsl:for-each select=".//@value[generate-id() = generate-id(key('values', concat($id, '|', .))[1])]">

Try this XSLT

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

  <xsl:key name="values" match="@value" use="concat(generate-id(ancestor::Product), '|', .)" />

  <xsl:template match="Product">
    <xsl:variable name="id" select="generate-id()" />
    <xsl:copy>
        <xsl:for-each select=".//@value[generate-id() = generate-id(key('values', concat($id, '|', .))[1])]">
            <values><xsl:value-of select="." /></values>
        </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Note, if you could upgrade to XSLT 2.0 then you could use xsl:for-each-group like so

<xsl:for-each-group select=".//@value" group-by=".">

Or you could use distinct-values(), like so

<xsl:for-each select="distinct-values(.//@value)">
Tim C
  • 70,053
  • 14
  • 74
  • 93