3

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 !

4
  • 1
    Are you asking "how do I supply the value of brandsSelect?" ? Or are you asking "how do I apply the filter in the xslt?" ? Commented Mar 29, 2018 at 13:20
  • How do I apply the filter in the xslt :) Commented Mar 29, 2018 at 13:24
  • Here is an example about using params: learn.microsoft.com/en-us/dotnet/standard/data/xml/… but how to filter is probably a XSL-only question. Haven't done that before. Commented Mar 29, 2018 at 13:28
  • Hm, I found this: msdn.microsoft.com/en-us/library/ms950734.aspx Commented Mar 29, 2018 at 13:30

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.