Xml XSLT-xsl:排序问题
我有一个需要排序的XML文件。在使用它的开发人员告诉我将XML更改为具有type=label-to-label节点属性的项之前,它一直工作得很好。不擅长XSLT。需要在“排序”节点上排序 (简化的)XML如下所示: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>
<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.