проблема с сортировкой <xsl: sort ...> в .NET 4 - PullRequest
1 голос
/ 24 июня 2011

У меня проблема при компиляции моей программы с .NET 4 в качестве целевой платформы. Сортировка с не работает.

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>
<employees>
    <name>Knight</name>
    <name>Cook</name>
    <name>Superman</name>
    <name>Yoda</name>
    <name>Albright</name>
</employees>
</daten>

Таблица стилей - "Daten.xsl":

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:output method="xml" encoding="utf-8" indent="yes"/>

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

Вы можете вызвать программу с помощью: ExampleSortProblemServer.exe Daten.xml Daten.xsl

Ожидаемый заказ должен быть:

Олбрайт Кук Найт Супермен Йода

Есть идеи, что не так?

Ответы [ 2 ]

2 голосов
/ 24 июня 2011

Я думаю, это потому, что вы пытаетесь отсортировать daten, а не names.

Например, эта таблица стилей:

<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>

с вашим вводом "Daten.xml":

<daten>
  <employees>
    <name>Knight</name>
    <name>Cook</name>
    <name>Superman</name>
    <name>Yoda</name>
    <name>Albright</name>
  </employees>
</daten>

производит этот вывод:

Albright Cook Knight Superman Yoda

EDIT

Таблица стилей требует лишь небольшого обновления для обработки ввода 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>

с обновленной таблицей стилей:

<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 
0 голосов
/ 30 июня 2011

Здесь расширенный 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>

Результат должен быть таким:

Олбрайт Чарльз
Олбрайт Марк
Олбрайт Питер
Кук Чарльз
Повар Томас
Рыцарь Гилберт
Рыцарь Питер
Супермен Кал-Эл
Йода

...