使用XSL排序问题 [英] Problem with XSL sorting

查看:182
本文介绍了使用XSL排序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,试图与使用XslCompiledTransform在CLR4.0 XSL文件进行排序。下面是我的示例XML文件(注:还有之后的第二个空格<富> 元素):

 < XML版本=1.0编码=UTF-8&GT?;
<反射>
  <原料药>
    < API ID =A>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
    < API ID =B>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
  < /原料药>
< /反射>
 

当我申请以下XSL文件:

 < XML版本=1.0&GT?;
< XSL:样式的xmlns:XSL =htt​​p://www.w3.org/1999/XSL/Transform版本=1.1>
  < XSL:模板匹配=/>
    < HTML>
      <身体GT;
        <表>
          < XSL:申请-模板选择=/反射/原料药/ API>
                        < XSL:排序选择=@ ID/>
                    < / XSL:申请 - 模板>
        < /表>
      < /身体GT;
    < / HTML>
  < / XSL:模板>
  < XSL:模板匹配=API>
    &其中; TR>
      < TD>
        < XSL:value-of的选择=@ ID/>
      < / TD>
    < / TR>
  < / XSL:模板>
< / XSL:样式>
 

我得到以下结果:

 < HTML>
  <身体GT;
    <表>
      &其中; TR>
        < TD> B< / TD>
      < / TR>
      &其中; TR>
        < TD>在< / TD>
      < / TR>
    < /表>
  < /身体GT;
< / HTML>
 

不过,如果我之后的第二删除空格<富> 元素,生成的文件是正确排序。这似乎是它可能在XslCompiledTransform的错误,但我希望有人可能有一个解决办法。

编辑:如果有人有麻烦复制它,这里是code我使用的:

  XslCompiledTransform XSLT =新XslCompiledTransform();
XsltSettings transformSettings =新XsltSettings(真实的,真正的);
xslt.Load(CreateVSToc.xsl,transformSettings,新XmlUrlResolver());

XmlReaderSettings readerSettings =新XmlReaderSettings();
readerSettings.IgnoreWhitespace =真;
流readStream = File.open方法(reflection.xml,FileMode.Open,FileAccess.Read,FileShare.ReadWrite | FileShare.Delete);
使用(XmlReader的读者= XmlReader.Create(readStream,readerSettings))
{
    流的OutputStream = File.open方法(toc.xml文件,FileMode.Create,FileAccess.Write,FileShare.Read | FileShare.Delete);
    使用(XmlWriter的作家= XmlWriter.Create(OutputStream中,xslt.OutputSettings))
    {

        争论的XsltArgumentList =新的XsltArgumentList();
        xslt.Transform(读卡器,参数,作家);
    }
}
 

解决方案

@Russ费里,感谢您的回答。它指出我朝着正确的方向发展。它出现在XslCompiledTransform的错误是,当你想通过一个元素的属性进行排序,它实际上排序由该元素的第一个子元素的值。因此,作为拉斯指出,这将正确地与我原来的转换文件进行排序:

 <反射>
  <原料药>
    < API ID =C>
      < ID> C< / ID>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
    < API ID =B>
      < ID> B< / ID>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
  < /原料药>
< /反射>
 

不过,所以才会这样的:

 <反射>
  <原料药>
    < API ID =C>
      &其中; anyElementName>℃下/ anyElementName>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
    < API ID =B>
      < anyElementName> B< / anyElementName>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
  < /原料药>
< /反射>
 

事实上,属性名完全被忽略,所以如果我运行变换是这样的:

 <反射>
  <原料药>
    < API ID =C>
      < anyElementName> Z< / anyElementName>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
    < API ID =A>
      < anyElementName> Y< / anyElementName>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
    < API ID =B>
      &其中; anyElementName&X的催化剂&其中; / anyElementName>
      < FOOS>
        <富/>
      < / FOOS>
    < / API>
  < /原料药>
< /反射>
 

结果是这样的:

 < HTML>
  <身体GT;
    <表>
      &其中; TR>
        < TD> B< / TD>
      < / TR>
      &其中; TR>
        < TD>在< / TD>
      < / TR>
      &其中; TR>
        &其中; TD>℃下; / TD>
      < / TR>
    < /表>
  < /身体GT;
< / HTML>
 

这是正确的排序,如果你被排序< anyElementName> 元素

I am having a problem trying to sort with an XSL file using the XslCompiledTransform in CLR4.0. Here is my sample XML file (Note: there is a space after the second <foo> element):

<?xml version="1.0" encoding="utf-8"?>
<reflection> 
  <apis>
    <api id="A">
      <foos>
        <foo/>
      </foos>
    </api>
    <api id="B">
      <foos>
        <foo/> 
      </foos>
    </api>     
  </apis>
</reflection>

When I apply the following XSL file:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
  <xsl:template match="/">
    <html>
      <body>
        <table>
          <xsl:apply-templates select="/reflection/apis/api">
                        <xsl:sort select="@id" />
                    </xsl:apply-templates>          
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="api">
    <tr>
      <td>
        <xsl:value-of select="@id" />
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

I get the following result:

<html>
  <body>
    <table>
      <tr>
        <td>B</td>
      </tr>
      <tr>
        <td>A</td>
      </tr>
    </table>
  </body>
</html>

However, if I remove the space after the second <foo> element, the resulting file is sorted correctly. This seems like it's probably a bug in the XslCompiledTransform, but I was hoping someone might have a workaround.

Edit: If anyone is having trouble reproducing it, here is the code I am using:

XslCompiledTransform xslt = new XslCompiledTransform();
XsltSettings transformSettings = new XsltSettings(true, true);
xslt.Load("CreateVSToc.xsl", transformSettings, new XmlUrlResolver());

XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.IgnoreWhitespace = true;
Stream readStream = File.Open("reflection.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
using (XmlReader reader = XmlReader.Create(readStream, readerSettings))
{
    Stream outputStream = File.Open("toc.xml", FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete);
    using (XmlWriter writer = XmlWriter.Create(outputStream, xslt.OutputSettings))
    {

        XsltArgumentList arguments = new XsltArgumentList();
        xslt.Transform(reader, arguments, writer);
    }
}

解决方案

@Russ Ferri, thanks for your answer. It pointed me in the right direction. It appears the bug in the XslCompiledTransform is that when you want to sort by an attribute of an element, it actually sorts by the value of the first child element of that element. So as Russ pointed out, this will sort correctly with my original transform file:

<reflection>
  <apis>
    <api id="C">
      <id>C</id>
      <foos>
        <foo/>
      </foos>
    </api>
    <api id="B">
      <id>B</id>
      <foos>
        <foo/>
      </foos>
    </api>
  </apis>
</reflection>

But so will this:

<reflection>
  <apis>
    <api id="C">
      <anyElementName>C</anyElementName>
      <foos>
        <foo/>
      </foos>
    </api>
    <api id="B">
      <anyElementName>B</anyElementName>
      <foos>
        <foo/>
      </foos>
    </api>
  </apis>
</reflection>

In fact, the attribute name is completely ignored, so if I run the transform on something like this:

<reflection>
  <apis>
    <api id="C">
      <anyElementName>Z</anyElementName>
      <foos>
        <foo/>
      </foos>
    </api>
    <api id="A">
      <anyElementName>Y</anyElementName>
      <foos>
        <foo/>
      </foos>
    </api>
    <api id="B">
      <anyElementName>X</anyElementName>
      <foos>
        <foo/>
      </foos>
    </api>
  </apis>
</reflection>

The result looks like this:

<html>
  <body>
    <table>
      <tr>
        <td>B</td>
      </tr>
      <tr>
        <td>A</td>
      </tr>
      <tr>
        <td>C</td>
      </tr>
    </table>
  </body>
</html>

Which is the correct sorting if you were sorting by the <anyElementName> elements

这篇关于使用XSL排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆