Reputation: 161
I have some situation in XSL that I can't figure out how to resolve.
I have the following xml, and I want to show only the main nodes that have at least one item enabled by the config/enable-items nodes.
Any hints?
Thanks in advance.
xml:
<xml>
<main name="Main Section 1" id="1">
<item id="a">
</item>
<item id="b">
</item>
<item id="c">
</item>
</main>
<main name="Main Section 2" id="2">
<item id="d">
</item>
<item id="e">
</item>
<item id="f">
</item>
</main>
<config>
<enable-items>
<item id="a" />
<item id="b" />
</enable-items>
</config>
</xml>
Wanted output:
Main Section 1:
* a
* b
p.s.: I've tried something using key, defining a key for the enable-items indexed by the id attribute, and doing a for-each on the items to define a variable ... But with no luck, :(, I still don't know how check the items inside main before showing the main @name attribute ...
Upvotes: 2
Views: 131
Reputation: 2327
The following:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="/input">
<xsl:variable name="keys" select="config/enable-items/item/@id" as="xs:string+"/>
<xsl:variable name="items" select="main/item[@id = $keys]"/>
<xsl:for-each select="$items/..">
<xsl:variable name="main" select="."/>
<xsl:value-of select="@name"/>
<xsl:text>: </xsl:text>
<xsl:for-each select="$items intersect $main/item">
<xsl:text> * </xsl:text>
<xsl:value-of select="@id"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
applied to your input (where I've changed the root element name to input
, as xml
is not a valid element name), produces:
Main Section 1:
* a
* b
If you change the second config item to e
, it produces the following:
Main Section 1:
* a
Main Section 2:
* e
Upvotes: 1
Reputation: 161
Well,
I was trying it using a more complex xml, on a real world application. When I did this example to post here, I managed to get it working :)
Follow the answer:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="enable-items" match="config/enable-items/item" use="@id"/>
<xsl:template match="/xml">
<xsl:apply-templates select="main" />
</xsl:template>
<xsl:template match="main">
<xsl:if test="key('enable-items', item/@id)">
<h1><xsl:value-of select="@name"/> </h1>
<xsl:for-each select="key('enable-items', item/@id)">
<xsl:value-of select="@id" /> <br>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1