【问题标题】:ASP.NET: gridview sorting using XSLT not workingASP.NET:使用 XSLT 的 gridview 排序不起作用
【发布时间】:2017-07-29 10:41:05
【问题描述】:

我对 XML-XSLT 编码很陌生。 我使用 XSLT 将 XmlDataSource 绑定到我的 gridview。我想在单击标题时对列进行排序。我不想将xml转换为数据集并绑定到gridview来实现排序。这是我的代码:

<asp:XmlDataSource ID="XmlDataSource1" runat="server"></asp:XmlDataSource>
<asp:GridView ID="gvResult" runat="server" HorizontalAlign="Center" AutoGenerateColumns="false" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" AllowPaging="True"
    OnPageIndexChanging="gvResult_PageIndexChanging" AllowSorting="true" OnSorting="gvResult_Sorting">
    <Columns>
        <asp:TemplateField HeaderText="ID" SortExpression="ID">
            <ItemTemplate>
                <asp:HyperLink runat="server" NavigateUrl='~/NewForm.aspx?ID=<%# XPath("@ID") %>'> 
                    <%# XPath("@ID") %>
                </asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="employee_number" HeaderText="Employee Number"  SortExpression="last_name"/>
        <asp:BoundField DataField="name" HeaderText="Employee Name" SortExpression="last_name" />
        <asp:BoundField DataField="date_joining" HeaderText="Joining Date" SortExpression="date_joining" />
        <asp:BoundField DataField="date_paid" HeaderText="Date Paid" SortExpression="last_name"/>
        <asp:BoundField DataField="amount" HeaderText="Salary"  />
        <asp:BoundField DataField="status" HeaderText="Status" />
    </Columns>
</asp:GridView>


protected void gvResult_Sorting(object sender, GridViewSortEventArgs e)
    {
         XsltArgumentList xslTrnsform = new XsltArgumentList();
        switch (e.SortExpression)
        {
            case "employee_number":
                xslTrnsform.AddParam("sortby", "", "employee_number");
                xslTrnsform.AddParam("order", "", "ascending");
                //xslTrnsform.AddParam("datatype", "", "number");
                break;
            case "date_joining":
                xslTrnsform.AddParam("sortby", "", "@date_joining");
                xslTrnsform.AddParam("order", "", "ascending");
                //xslTrnsform.AddParam("data-type", "", "text");
                break;
            case "date_paid":
                xslTrnsform.AddParam("sortby", "", "@date_paid");
                xslTrnsform.AddParam("order", "", "ascending");
                //xslTrnsform.AddParam("data-type", "", "text");
                break;
        }

        XmlDataSource1.EnableCaching = false;
        XmlDataSource1.Data = ResponseObj.OuterXml;

        XmlDataSource1.TransformArgumentList = xslTrnsform;
        XmlDataSource1.TransformFile = "employees.xslt";
        XmlDataSource1.XPath = "/employees/employee"; ;

        // Bind the DataSet to the grid view
        gvResult.DataSource = XmlDataSource1;
        gvResult.DataBind();
        gvResult.Visible = true;
    }



<?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:output method="xml" indent="yes"/>

  <xsl:param name="sortby" select="@employee_number"/>
  <xsl:param name="order" select="'ascending'"/>

  <xsl:template match="employees">
    <employees>
    <xsl:apply-templates select="employee">
      <xsl:sort select="*[name()=$sortby]" order="{$order}" />
    </xsl:apply-templates>
    </employees>
  </xsl:template>


  <xsl:template match="employee">
    <employee>
      <xsl:attribute name="ID">
        <xsl:value-of select="@ID"/>
      </xsl:attribute>
      <xsl:attribute name="employee_number">
        <xsl:value-of select="@employee_number"/>
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@last_name"/>, <xsl:value-of select="@first_name"/>
      </xsl:attribute>
      <xsl:attribute name="date_joining">
        <xsl:value-of select="@date_joining" />
      </xsl:attribute>
      <xsl:attribute name="dte_to_date">
        <xsl:value-of select="@dte_to_date" />
      </xsl:attribute>
      <xsl:attribute name="date_paid">
        <xsl:value-of select="@date_paid"/>
      </xsl:attribute>
      <xsl:attribute name="date_paid">
        <xsl:value-of select="@date_paid"/>
      </xsl:attribute>
      <xsl:attribute name="amount">
        <xsl:value-of select="@amount"/>
      </xsl:attribute>
      <xsl:attribute name="status">
      <xsl:value-of select="@status"/>
      </xsl:attribute>
    </employee>
  </xsl:template>
</xsl:stylesheet>

数据显示在网格视图上。但是当我点击标题时,什么也没有发生。我还必须对由姓氏、名字组成的“名称”列进行排序。

【问题讨论】:

  • 为什么要使用这种冗长的 xsl:element/xsl:attribute 格式?要么使用 AVT:&lt;employee ID="{@ID}" empNr="{@empNr}" etc/&gt;,要么使用 &lt;xsl:copy-of select="@*"/&gt;

标签: c# asp.net xml xslt gridview


【解决方案1】:

您遇到的一个问题是您设置sortby 参数的方式不一致。您可以在一个地方执行此操作...

 xslTrnsform.AddParam("sortby", "", "employee_number");

但是在另一个地方你这样做......

 xslTrnsform.AddParam("sortby", "", "@date_joining");

由于您的所有数据看起来都保存在属性中,为了保持一致性,在所有情况下删除 @ 前缀可能会更容易。然后,你的xsl:sort 可以是这样的

 <xsl:sort select="@*[name()=$sortby]" order="{$order}" />

(之前您正在执行select="*[name()=$sortby],它将查找元素而不是属性。)

要让您的name 列按last_namefirst_name 排序,您可以添加第二个排序参数

case "name":
   xslTrnsform.AddParam("sortby", "", "last_name");
   xslTrnsform.AddParam("sortbysecond", "", "first_name");
   xslTrnsform.AddParam("order", "", "ascending");
   break;

然后,假设您在 XSLT 中声明 sortbysecond 参数,您的排序将如下所示

<xsl:apply-templates select="employee">
  <xsl:sort select="@*[name()=$sortby]" order="{$order}" />
  <xsl:sort select="@*[name()=$sortbysecond]" order="{$order}" />
</xsl:apply-templates>

试试这个 XSLT...

<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:output method="xml" indent="yes"/>

  <xsl:param name="sortby" select="'employee_number'"/>
  <xsl:param name="sortbysecond" select="'employee_number'"/>
  <xsl:param name="order" select="'descending'"/>

  <xsl:template match="employees">
    <employees>
    <xsl:apply-templates select="employee">
      <xsl:sort select="@*[name()=$sortby]" order="{$order}" />
      <xsl:sort select="@*[name()=$sortbysecond]" order="{$order}" />
    </xsl:apply-templates>
    </employees>
  </xsl:template>

  <xsl:template match="employee">
    <employee ID="{@ID}" 
              employee_number="{@employee_number}"
              name="{@last_name}, {@first_name}"
              date_joining="{@data_joining}"
              dte_to_date="{@dte_to_date}"
              date_paid="{@date_paid}"
              date_paid="{@date_paid}"
              amount="{@amount}"
              status="{@status}">
    </employee>
  </xsl:template>
</xsl:stylesheet>

注意 Attribute Value Templates 的使用,正如 Michael Kay 在 cmets 中提到的那样,它极大地简化了您的 XSLT。

【讨论】:

  • 很抱歉,我没有时间尝试。谢谢蒂姆和迈克尔。排序现在正在工作。 Tim,你提供的代码我已经测试过了。
猜你喜欢
  • 2018-04-11
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多