我有一个需要排序的XML文件。工作得很好,直到dev使用它告诉我将XML更改为我具有type = 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(当我只是排序'items'时)看起来像这样:
<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: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: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>...
答案 0 :(得分:3)
XSLT为节点提供默认匹配模板,其中节点的文本内容已经过时。
在您提供的XSLT中,您已经在频道模板中处理了元素标题,链接和说明,您需要创建空模板,以便在您的频道模板中调试apply-templates。例如:
<xsl:template match="title|link|description"/>
这应该会吸引你的“落后者”。
答案 1 :(得分:3)
此样式表:
<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>
注意:身份规则。排序channel
子项:数字排序键的NaN
值首先排序。虽然这是正常的行为,但直到XSLT 2.0才明确定义了http://www.w3.org/TR/xslt20/#comparing-sort-keys:
NaN值,用于排序目的,是 被认为彼此相等, 并且少于任何其他数值。
编辑:我不确定,但在搜索之后,这也是errata document中XSLT 1.0规范的一部分:
按升序排列NaN先于全部 其他数值和降序 命令它跟随它们
答案 2 :(得分:1)
为了避免必须“硬编码”特定“stragglers”的名称(否则将由默认匹配模板选取),您可以在这种情况下添加自己的默认模板,以简单地忽略此类节点。 / p>
<xsl:template match="@*|node()">
<xsl:apply-templates />
</xsl:template>
这匹配任何非特定节点,并简单地忽略它,并继续处理子节点(这样当它与'rss'节点匹配时,它可以继续匹配'channel'节点)。您对“频道”,“项目”和“标签”的特定模板匹配优先于此。
因此,如果您采用以下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>