Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSLT-xsl:排序问题_Xml_Xslt_Sorting - Fatal编程技术网

Xml XSLT-xsl:排序问题

Xml XSLT-xsl:排序问题,xml,xslt,sorting,Xml,Xslt,Sorting,我有一个需要排序的XML文件。在使用它的开发人员告诉我将XML更改为具有type=label-to-label节点属性的项之前,它一直工作得很好。不擅长XSLT。需要在“排序”节点上排序 (简化的)XML如下所示: <rss> <channel> <title>This is the title</title> <link>http://www.mydomain.com/</link>

我有一个需要排序的XML文件。在使用它的开发人员告诉我将XML更改为具有type=label-to-label节点属性的项之前,它一直工作得很好。不擅长XSLT。需要在“排序”节点上排序

(简化的)XML如下所示:

<rss>
   <channel>
       <title>This is the title</title>
       <link>http://www.mydomain.com/</link>
       <description>The Description</description>
       <label>
           <title>Another Label</title>
           <sort>4</sort>
       </label>
       <item>
           <title>An Item</title>
           <sort>2</sort>
       </item>
       <item>
           <title>One Item</title>
           <sort>3</sort>
       </item>
       <label>
           <title>A Label</title>
           <sort>1</sort>
       </label>
   </channel>
</rss>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />
     <xsl:template match="channel">
        <rss>
           <channel>
              <xsl:copy-of select="title"/>
              <xsl:copy-of select="link"/>
              <xsl:copy-of select="description"/>
              <xsl:apply-templates select="item">
                  <xsl:sort select="sort" data-type="number"/>
              </xsl:apply-templates>
           </channel>
        </rss>
    </xsl:template>

    <xsl:template match="item">
        <xsl:copy-of select="." />
    </xsl:template> 
 </xsl:stylesheet>

这是标题
http://www.mydomain.com/
描述
另一个标签
4.
项目
2.
一项
3.
标签
1.
旧的XSL(当我刚刚对“项”进行排序时)如下所示:

<rss>
   <channel>
       <title>This is the title</title>
       <link>http://www.mydomain.com/</link>
       <description>The Description</description>
       <label>
           <title>Another Label</title>
           <sort>4</sort>
       </label>
       <item>
           <title>An Item</title>
           <sort>2</sort>
       </item>
       <item>
           <title>One Item</title>
           <sort>3</sort>
       </item>
       <label>
           <title>A Label</title>
           <sort>1</sort>
       </label>
   </channel>
</rss>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />
     <xsl:template match="channel">
        <rss>
           <channel>
              <xsl:copy-of select="title"/>
              <xsl:copy-of select="link"/>
              <xsl:copy-of select="description"/>
              <xsl:apply-templates select="item">
                  <xsl:sort select="sort" data-type="number"/>
              </xsl:apply-templates>
           </channel>
        </rss>
    </xsl:template>

    <xsl:template match="item">
        <xsl:copy-of select="." />
    </xsl:template> 
 </xsl:stylesheet>

我试着这样想,它会起作用,而且大部分是这样,但我遇到了各种各样的“掉队者”


当使用最新的XSL时,“掉队者”看起来是这样的:

<rss xmlns:st="http://ww2.startribune.com/rss/modules/base/">
  <channel>
    <title>A Title</title>
    <link>http://www.mydomain.com/</link>
    <description>The Description</description>
A Title
http://www.mydomain.com/
The Description
        <label>...
    <item>...

头衔
http://www.mydomain.com/
描述
头衔
http://www.mydomain.com/
描述
...
...

XSLT为节点提供了一个默认匹配模板,其中输出节点的文本内容

在您提供的XSLT中,您已经在处理频道模板中的元素title、link和description,由于频道模板中的apply templates调用,您需要创建空模板来吸收它们。例如:

<xsl:template match="title|link|description"/>


XSLT为节点提供了一个默认的匹配模板,其中输出节点的文本内容

在您提供的XSLT中,您已经在处理频道模板中的元素title、link和description,由于频道模板中的apply templates调用,您需要创建空模板来吸收它们。例如:

<xsl:template match="title|link|description"/>


这将吸收你的“散乱者”。

为了避免必须“硬编码”特定“散乱者”的名称,否则将由默认匹配模板拾取,在这种情况下,你可以添加自己的默认模板,以忽略此类节点

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

这将匹配任何非特定节点,并忽略它,然后继续处理子节点(这样,当它匹配“rss”节点时,它就可以继续匹配“通道”节点)。“频道”、“项目”和“标签”的特定模板匹配将优先于此

因此,如果采用以下XSLT

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

   <xsl:template match="channel">
      <rss>
         <channel>
            <xsl:copy-of select="title"/>
            <xsl:copy-of select="link"/>
            <xsl:copy-of select="description"/>
            <xsl:apply-templates>
               <xsl:sort select="sort"/>
            </xsl:apply-templates>
         </channel>
      </rss>
   </xsl:template>

   <xsl:template match="item">
      <xsl:copy-of select="."/>
   </xsl:template>

   <xsl:template match="label">
      <xsl:copy-of select="."/>
   </xsl:template>

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

并将其应用于简化的XML,您将获得以下输出

<rss>
   <channel>
      <title>This is the title</title>
      <link>http://www.mydomain.com/</link>
      <description>The Description</description>
      <label>
         <title>A Label</title>
         <sort>1</sort>
      </label>
      <item>
         <title>An Item</title>
         <sort>2</sort>
      </item>
      <item>
         <title>One Item</title>
         <sort>3</sort>
      </item>
      <label>
         <title>Another Label</title>
         <sort>4</sort>
      </label>
   </channel>
</rss>

这是标题
http://www.mydomain.com/
描述
标签
1.
项目
2.
一项
3.
另一个标签
4.

为了避免必须“硬编码”特定“掉队者”的名称,否则会被默认匹配模板拾取,在这种情况下,您可以添加自己的默认模板,以忽略此类节点

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

这将匹配任何非特定节点,并忽略它,然后继续处理子节点(这样,当它匹配“rss”节点时,它就可以继续匹配“通道”节点)。“频道”、“项目”和“标签”的特定模板匹配将优先于此

因此,如果采用以下XSLT

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

   <xsl:template match="channel">
      <rss>
         <channel>
            <xsl:copy-of select="title"/>
            <xsl:copy-of select="link"/>
            <xsl:copy-of select="description"/>
            <xsl:apply-templates>
               <xsl:sort select="sort"/>
            </xsl:apply-templates>
         </channel>
      </rss>
   </xsl:template>

   <xsl:template match="item">
      <xsl:copy-of select="."/>
   </xsl:template>

   <xsl:template match="label">
      <xsl:copy-of select="."/>
   </xsl:template>

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

并将其应用于简化的XML,您将获得以下输出

<rss>
   <channel>
      <title>This is the title</title>
      <link>http://www.mydomain.com/</link>
      <description>The Description</description>
      <label>
         <title>A Label</title>
         <sort>1</sort>
      </label>
      <item>
         <title>An Item</title>
         <sort>2</sort>
      </item>
      <item>
         <title>One Item</title>
         <sort>3</sort>
      </item>
      <label>
         <title>Another Label</title>
         <sort>4</sort>
      </label>
   </channel>
</rss>

这是标题
http://www.mydomain.com/
描述
标签
1.
项目
2.
一项
3.
另一个标签
4.
此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="channel">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()">
                <xsl:sort select="sort" data-type="number"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<rss>
    <channel>
        <title>This is the title</title>
        <link>http://www.mydomain.com/</link>
        <description>The Description</description>
        <label>
            <title>A Label</title>
            <sort>1</sort>
        </label>
        <item>
            <title>An Item</title>
            <sort>2</sort>
        </item>
        <item>
            <title>One Item</title>
            <sort>3</sort>
        </item>
        <label>
            <title>Another Label</title>
            <sort>4</sort>
        </label>
    </channel>
</rss>

这是标题
http://www.mydomain.com/
描述
标签
1.
项目
2.
一项
3.
另一个标签
4.
注意:标识规则。排序
channel
childrens:
NaN
数字排序键的值排在第一位。尽管这是正常的行为,但直到XSLT 2.0才明确定义了这一行为,从:

出于排序目的,NaN值为 被认为是平等的, 并且小于任何其他数值

编辑:我不确定,但在搜索之后,这也是XSLT 1.0规范的一部分:

按升序,一个NaN优先于所有NaN 以降序排列的其他数值和 命令它跟着他们

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="channel">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()">
                <xsl:sort select="sort" data-type="number"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<rss>
    <channel>
        <title>This is the title</title>
        <link>http://www.mydomain.com/</link>
        <description>The Description</description>
        <label>
            <title>A Label</title>
            <sort>1</sort>
        </label>
        <item>
            <title>An Item</title>
            <sort>2</sort>
        </item>
        <item>
            <title>One Item</title>
            <sort>3</sort>
        </item>
        <label>
            <title>Another Label</title>
            <sort>4</sort>
        </label>
    </channel>
</rss>

这是标题
http://www.mydomain.com/
描述
标签
1.
项目
2.
一项
3.
另一个标签
4.