Distinct Attribute Names with XSL

D

Damien

I have seen examples of selecting distinct elements by name, but my
issue is that I need to get distinct attributes by name. My XML looks
like:

<root>
<file>
<rows>
<row att1="1" />
<row att2="2" />
<row att1="1" att2="2" />
</rows>
</file>
<file>
<rows>
<row att3="1" />
<row />
<row att4="2" />
</rows>
</file>
</root>

For each file element, I want to return a distinct list of attribute
names. I'm trying to create an HTML table based on this data in an
XSL. For example:
+-------+--------+
| attr1 | attr 2 |
+-------+--------+
| 1 | N/A |
+-------+--------+
| N/A | 2 |
+-------+--------+
| 1 | 2 |
+-------+--------+

+-------+--------+
| attr3 | attr 4 |
+-------+--------+
| 1 | N/A |
+-------+--------+
| N/A | N/A |
+-------+--------+
| N/A | 2 |
+-------+--------+

I'm sure the Muenchian Technique is the thing to use (utilizing a
custom @use clause on the <xsl:key> to "group by" the file element),
but I can't seem to get it to work correctly for the attributes.

Thanks in advance for your help.
-Damien
 
P

Pavel Lepin

Damien said:
I have seen examples of selecting distinct elements by
name, but my issue is that I need to get distinct
attributes by name.

<root>
<file>
<rows>
<row att1="1" />
<row att2="2" />
<row att1="1" att2="2" />
</rows>
</file>
<file>
<rows>
<row att3="1" />
<row />
<row att4="2" />
</rows>
</file>
</root>

For each file element, I want to return a distinct list of
attribute names. I'm trying to create an HTML table based
on this data in an XSL.

Here's a partial solution for you. It's a bit klugdy
(figuring out precisely what's kludgy about it is left as a
potentially enlightening exercise for the reader):

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="row-group-attrs" match="@*"
use="generate-id(ancestor-or-self::rows[1])"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="row-group-id">
<xsl:value-of
select="generate-id(ancestor-or-self::rows[1])"/>
</xsl:template>
<xsl:template match="row">
<xsl:variable name="this-row-group-id">
<xsl:call-template name="row-group-id"/>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates
select="key('row-group-attrs',$this-row-group-id)"
mode="group-attr">
<xsl:with-param name="context" select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="group-attr">
<xsl:param name="context"/>
<xsl:variable
name="source-attr"
select=
"
$context/@*
[
local-name()=local-name(current()) and
namespace-uri()=namespace-uri(current())
]
"/>
<xsl:choose>
<xsl:when test="$source-attr">
<xsl:apply-templates select="$source-attr"/>
</xsl:when>
<xsl:eek:therwise>
<xsl:attribute
name="{local-name()}"
namespace="{namespace-uri()}"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top