Search code examples
asp.netxmlxsltxmldatasource

How do I pass a xml attribute to xslt parameter?


I got everything working (thank empo) except the ctrlname column. I don't know the syntax well enough. What I am trying to do is use the xslt to sort the xml in the gridview by the column name. Everything is working but the ctrlname column. How do I pass an attribute to the XSLT? I've tried: @name, Data/@name, Data[@name], ctrlname. Nothing works.

    XmlDataSource1.EnableCaching = False
    Dim xslTrnsform As System.Xml.Xsl.XsltArgumentList = New System.Xml.Xsl.XsltArgumentList
    xslTrnsform.AddParam("sortby", "", sortAttr)
    xslTrnsform.AddParam("orderas", "", orderby)
    XmlDataSource1.TransformArgumentList = xslTrnsform
    XmlDataSource1.DataFile = "~/App_LocalResources/DST_Test.xml"
    XmlDataSource1.XPath = "//data"
    XmlDataSource1.TransformFile = xsltFileName
    'XmlDataSource1.DataBind()
    GridView1.DataSource = XmlDataSource1
    GridView1.DataBind()

XSL

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

    <xsl:param name="sortby"></xsl:param>
    <xsl:param name="orderas"></xsl:param>

    <xsl:output method="xml" indent="yes"/>

    <!--<xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>-->
    <xsl:template match="root">
        <root>
            <xsl:apply-templates select="data">
                <xsl:sort select="*[name()=$sortby]" data-type="text" order="{$orderas}"/>
            </xsl:apply-templates>
        </root>
    </xsl:template>
    <xsl:template match="data">
        <data>
            <xsl:attribute name="ctrlname">
                <xsl:value-of select="@name"/>
            </xsl:attribute>
            <xsl:attribute name="value">
                <xsl:value-of select="value" />
            </xsl:attribute>
            <xsl:attribute name="comment">
                <xsl:value-of select="comment" />
            </xsl:attribute>
        </data>
    </xsl:template>
</xsl:stylesheet>

XML input

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <data name="Test1.Text" xml:space="preserve">
        <value>Please Pick Bare Pump</value>
        <comment>Tab - Pump Configuration</comment>
    </data>
    <data name="Test2.Text" xml:space="preserve">
        <value>Complete</value>
        <comment>A07</comment>
    </data>
    <data name="Test3.Text" xml:space="preserve">
        <value>Confirmed</value>
        <comment>A01</comment>
    </data>
</root>

Solution

  • Yes, I'm sorry didnt notice that you wanted also sort by attributes. Note also that you have changed the syntax of xsl:param and it's not correct in that way. It's very important that you keep the single quotes inside the double ones. Here is the final template:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    
            <xsl:param name="sortby" select="'value'"/>
            <xsl:param name="orderas" select="'ascending'"/>
    
        <xsl:output method="xml" indent="yes"/>
    
        <!--<xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>-->
        <xsl:template match="root">
            <root>
                <xsl:apply-templates select="data">
                    <xsl:sort select="*[name()=$sortby]|@*[name()=$sortby]" data-type="text" order="{$orderas}"/>
                </xsl:apply-templates>
            </root>
        </xsl:template>
        <xsl:template match="data">
            <data>
                <xsl:attribute name="ctrlname">
                    <xsl:value-of select="@name"/>
                </xsl:attribute>
                <xsl:attribute name="value">
                    <xsl:value-of select="value" />
                </xsl:attribute>
                <xsl:attribute name="comment">
                    <xsl:value-of select="comment" />
                </xsl:attribute>
            </data>
        </xsl:template>
    </xsl:stylesheet>