使用<;xsl:sort…>;在.NET4中

使用<;xsl:sort…>;在.NET4中,.net,xml,xslt,c#-4.0,xsl-fo,.net,Xml,Xslt,C# 4.0,Xsl Fo,当我用.NET4作为目标框架编译程序时,我遇到了一个问题。与的排序不起作用 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml; using System.Xml.Xsl; namespace ExampleSortProblemServer { class Program { static

当我用.NET4作为目标框架编译程序时,我遇到了一个问题。与的排序不起作用

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Xsl;

namespace ExampleSortProblemServer
{
  class Program
  {
    static void Main(string[] args)
    {
        // argument is the filename
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(args[0]);

        XslCompiledTransform xslt = new XslCompiledTransform();
        XmlResourceResolver resolver = new XmlResourceResolver(typeof (IReport));
        xslt.Load(args[1]);

        String foStr = CreateFO(xmlDocument, xslt, resolver);

        Console.WriteLine(foStr);
    }

    public static string CreateFO(XmlNode doc, XslCompiledTransform xslt, XmlResolver resolver)
    {
        string fo;

        using (var stringReader = new StringReader(doc.OuterXml))
        {
            using (var xmlTextReader = new XmlTextReader(stringReader))
            {
                using (var stringWriter = new StringWriter())
                {
                    using (var xmlTextWriter = new XmlTextWriter(stringWriter))
                    {
                        try
                        {
                            xslt.Transform(xmlTextReader, null, xmlTextWriter, resolver);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                            throw;
                        }
                        stringWriter.Flush();
                        fo = stringWriter.ToString();
                    }
                }
            }
        }
        return fo;
    }
  }
}
数据为“Daten.xml”:


骑士
烹调
超人
尤达
奥尔布赖特
样式表是“Daten.xsl”:


您可以通过以下方式调用该程序: ExampleSortProblemServer.exe Daten.xml Daten.xsl

预期顺序应为:

奥尔布赖特库克骑士超人尤达


知道什么是不正确的吗?

我想这是因为您试图对
daten
进行排序,而不是对
名称进行排序

例如,此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:apply-templates select="*[local-name()='daten']/*[local-name()='employees']/*[local-name()='name']">
      <xsl:sort order="ascending"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="name">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:apply-templates select="*[local-name()='daten']/*[local-name()='employees']/*[local-name()='employee']">
      <xsl:sort order="ascending" select="name"/>
      <xsl:sort order="ascending" select="forename"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="name">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>

  <xsl:template match="forename">
    <xsl:apply-templates/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

编辑

样式表只需稍加更新即可处理作为答案添加的XML输入

此输入:

<daten>
  <employees>
    <employee>
      <name>Knight</name>
      <forename>Peter</forename>
    </employee>
    <employee>
      <name>Knight</name>
      <forename>Gilbert</forename>
    </employee>     
    <employee>
      <name>Cook</name>
      <forename>Thomas</forename>
    </employee>
    <employee>
      <name>Cook</name>
      <forename>Charles</forename>
    </employee>     
    <employee>
      <name>Superman</name>
      <forename>Kal-El</forename>
    </employee>
    <employee>
      <name>Yoda</name>
      <forename></forename>
    </employee>
    <employee>
      <name>Albright</name>
      <forename>Peter</forename>
    </employee>
    <employee>
      <name>Albright</name>
      <forename>Charles</forename>
    </employee> 
    <employee>
      <name>Albright</name>
      <forename>Mark</forename>
    </employee>     
  </employees>
</daten>

这里是一个扩展xml文件:

<daten>
<employees>
    <employee>
        <name>Knight</name>
        <forename>Peter</forename>
    </employee>
    <employee>
        <name>Knight</name>
        <forename>Gilbert</forename>
    </employee>     
    <employee>
        <name>Cook</name>
        <forename>Thomas</forename>
    </employee>
    <employee>
        <name>Cook</name>
        <forename>Charles</forename>
    </employee>     
    <employee>
        <name>Superman</name>
        <forename>Kal-El</forename>
    </employee>
    <employee>
        <name>Yoda</name>
        <forename></forename>
    </employee>
    <employee>
        <name>Albright</name>
        <forename>Peter</forename>
    </employee>
    <employee>
        <name>Albright</name>
        <forename>Charles</forename>
    </employee> 
    <employee>
        <name>Albright</name>
        <forename>Mark</forename>
    </employee>     
</employees>
</daten>

骑士
彼得
骑士
吉尔伯特
烹调
托马斯
烹调
查尔斯
超人
卡-艾尔
尤达
奥尔布赖特
彼得
奥尔布赖特
查尔斯
奥尔布赖特
做记号
结果应该是:

奥尔布赖特·查尔斯
奥尔布赖特马克
奥尔布赖特·彼得
库克·查尔斯
库克·托马斯
吉尔伯特骑士
彼得骑士
超人卡尔艾尔酒店
尤达

到目前为止,这似乎奏效了。但是:1。输出应该没有“名称”标签:
奥尔布赖特
库克
骑士
超人
尤达
2。如果我有几个级别的排序,解决方案是什么?例1。级别:名称2。级别:forname。。。所以得出这样的结果:
奥尔布赖特马克
奥尔布赖特彼得
库克查尔斯
库克托马斯


1。样式表的第一个版本只是为了演示正确的排序(让您开始)。我对它进行了修改,这样您就可以准确地获得所请求的输出。(我添加了一个模板来匹配
name
)2。请您添加另一个示例XML实例,以便我可以看到您用名称/forname描述的内容?@jahuer1-请查看我对一个稍微修改过的样式表的编辑,该样式表生成您想要的输出。@DevNull clean solution+1。也许,您可以省略
顺序
,因为默认情况下是“升序”,并使用
self::xxx
代替
local-name()。我保留了
顺序
,以便OP可以看到如何轻松更改顺序(无需再问其他问题)。我还在样式表中留下了
local-name()
,因为OP在他/她的样式表中就是这样的。我更喜欢
self::xxx
。它干净多了。我也喜欢你对另一个“答案”的评论使用
声明的连续
不需要大括号;如果省略除最里面的一对之外的所有代码,那么代码的可读性会更好(在这种情况下,标准缩进也不会缩进连续的使用。此外,XmlTextWriter构造函数被弃用,取而代之的是XmlWriter.Createfinally。最后,通常的最佳做法是不在帮助器方法内部进行常规异常记录;最好尽可能全局地进行此操作。只有捕获异常才能实际修复。Rea涉猎能力取决于个人…如果能给我一个解决问题的提示,我将不胜感激。我想找一个名叫尤达的同事。
Albright Cook Knight Superman Yoda
<daten>
  <employees>
    <employee>
      <name>Knight</name>
      <forename>Peter</forename>
    </employee>
    <employee>
      <name>Knight</name>
      <forename>Gilbert</forename>
    </employee>     
    <employee>
      <name>Cook</name>
      <forename>Thomas</forename>
    </employee>
    <employee>
      <name>Cook</name>
      <forename>Charles</forename>
    </employee>     
    <employee>
      <name>Superman</name>
      <forename>Kal-El</forename>
    </employee>
    <employee>
      <name>Yoda</name>
      <forename></forename>
    </employee>
    <employee>
      <name>Albright</name>
      <forename>Peter</forename>
    </employee>
    <employee>
      <name>Albright</name>
      <forename>Charles</forename>
    </employee> 
    <employee>
      <name>Albright</name>
      <forename>Mark</forename>
    </employee>     
  </employees>
</daten>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:apply-templates select="*[local-name()='daten']/*[local-name()='employees']/*[local-name()='employee']">
      <xsl:sort order="ascending" select="name"/>
      <xsl:sort order="ascending" select="forename"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="name">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>

  <xsl:template match="forename">
    <xsl:apply-templates/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

</xsl:stylesheet>
Albright Charles
Albright Mark
Albright Peter
Cook Charles
Cook Thomas
Knight Gilbert
Knight Peter
Superman Kal-El
Yoda 
<daten>
<employees>
    <employee>
        <name>Knight</name>
        <forename>Peter</forename>
    </employee>
    <employee>
        <name>Knight</name>
        <forename>Gilbert</forename>
    </employee>     
    <employee>
        <name>Cook</name>
        <forename>Thomas</forename>
    </employee>
    <employee>
        <name>Cook</name>
        <forename>Charles</forename>
    </employee>     
    <employee>
        <name>Superman</name>
        <forename>Kal-El</forename>
    </employee>
    <employee>
        <name>Yoda</name>
        <forename></forename>
    </employee>
    <employee>
        <name>Albright</name>
        <forename>Peter</forename>
    </employee>
    <employee>
        <name>Albright</name>
        <forename>Charles</forename>
    </employee> 
    <employee>
        <name>Albright</name>
        <forename>Mark</forename>
    </employee>     
</employees>
</daten>