Reputation: 33
I need to transform an XML file to another XML filtered. I want to use XSLT/C# to do this operation. My source code in C# will execute the XSLT file with a list of parameter (I'm using XslCompiledTransform class).
My question is : how in XSLT language I can parse all parameters transmited from the C# to filter the output XML file.
Example : a list of car
<cars>
<car brand="Audi" model="A4/>
<car brand="Audi" model="A6/>
<car brand="Audi" model="A7/>
<car brand="Volvo" model="V40" />
<car brand="Volvo" model="V60" />
<car brand="Honda" model="Civic" />
<car brand="Mercedes" model="Class E" />
</cars>
a simple XSLT with brandsSelect parameter
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="brandsSelect"></xsl:param>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
In my C# source code, I populate my variable : brandsSelect = Volvo, Honda
Expected result :
<cars>
<car brand="Volvo" model="V40" />
<car brand="Volvo" model="V60" />
<car brand="Honda" model="Civic" />
</cars>
Thanks for your help !
Upvotes: 3
Views: 165
Reputation: 70598
What you could do (in XSLT 1.0 which is what XSLTCompiledTransform implements) is to do a string test to see if the parameter "contains" the brand
attribute:
<xsl:template match="cars">
<xsl:copy>
<xsl:apply-templates select="car[contains($brandsSelect, @brand)]" />
</xsl:copy>
</xsl:template>
However, this will fail if one brand happens to be a substring of another (For example, if "Laudi" was brand as well as "Audi"
So, to make it robust, try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="brandsSelect">Volvo,Honda</xsl:param>
<xsl:variable name="brandMatcher" select="concat(',', $brandsSelect, ',')" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="cars">
<xsl:copy>
<xsl:apply-templates select="car[contains($brandMatcher, concat(',', @brand, ','))]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
It is important to note, the value of the brandsSelect
should not contain any spaces between the brands, only commas.
Upvotes: 3