C# XSLT条件排序

C# XSLT条件排序,c#,.net,xslt,xpath,C#,.net,Xslt,Xpath,我有以下XML: <Users> <User Id="1"> <Name>abc</Name> <LastName>d</LastName> </User> <User Id="2"> <Name></Name> <LastName>ab</LastName> <

我有以下XML:

<Users>
  <User Id="1">
    <Name>abc</Name>
    <LastName>d</LastName>
  </User>
  <User Id="2">
    <Name></Name>
    <LastName>ab</LastName>
  </User>
  <User Id="3">
    <Name>a</Name>
    <LastName>efg</LastName>
  </User>
</Users>

abc
D
ab
A.
efg
现在,我使用以下模板对用户进行排序:

<xsl:template match="Users">
  <Users>
    <xsl:for-each select="User">
      <xsl:sort select="Name"/>
      <xsl:sort select="LastName"/>

      <User>
        <xsl:attribute name="Id">
          <xsl:value-of select="attribute::Id"/>
        </xsl:attribute>
        <Name>
          <xsl:value-of select="Name"/>
        </Name>
        <LastName>
          <xsl:value-of select="LastName"/>
        </LastName>
      </User>
    </xsl:for-each>
  </Users>
</xsl:template>

但我需要排序,它满足以下条件:按名称排序。如果Name为空或null,则需要按LastName排序。因此,在生成的XML中,我需要以下顺序:User3、User2、User1

感谢您的帮助


注意:我使用ASP.NET 3.5

我将首先使用标识转换,然后将排序应用于元素的并集(不包括
名称
为空的元素)


当应用于问题中所示的输入时,我们获得:

<Users>
   <User Id="3">
      <Name>a</Name>
      <LastName>efg</LastName>
   </User>
   <User Id="2">
      <Name/>
      <LastName>ab</LastName>
   </User>
   <User Id="1">
      <Name>abc</Name>
      <LastName>d</LastName>
   </User>
</Users>

A.
efg
ab
abc
D

您可以选择带有谓词筛选器的
Name
LastName
元素,这些谓词筛选器使用
normalize-space()
来过滤空元素,使用union操作符
将它们组合起来,并将它们与perenthesis分组(这将在XSLT/XPath 2.0中创建一个序列)。然后,选择分组中用于排序的第一个

另外,您可以只使用
,而不是重新构造
元素


<Users>
   <User Id="3">
      <Name>a</Name>
      <LastName>efg</LastName>
   </User>
   <User Id="2">
      <Name/>
      <LastName>ab</LastName>
   </User>
   <User Id="1">
      <Name>abc</Name>
      <LastName>d</LastName>
   </User>
</Users>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />

<xsl:template match="Users">
  <Users>
    <xsl:for-each select="User">
      <xsl:sort select="(Name[normalize-space()]|LastName[normalize-space()])[1]"/>
        <xsl:copy-of select="."/>
    </xsl:for-each>
  </Users>
</xsl:template>

</xsl:stylesheet>