XSLT 复杂排序和分组
XSLT complex sorting and grouping
我有一个 XML 文件如下所示:
<components>
<comp>
<ref>q7</ref>
<partnumber>foo</partnumber>
</comp>
<comp>
<ref>q1</ref>
<partnumber>foo</partnumber>
</comp>
<comp>
<ref>q6</ref>
<partnumber>bar</partnumber>
</comp>
<comp>
<ref>q3</ref>
<partnumber>bar</partnumber>
</comp>
</components>
而且我需要按零件号组合并按参考号排序,这样输出文件将如下所示:
q1 q7, foo
q3 q6, bar
但我得到了这个输出:
q3 q6, bar
q1 q7, foo
这是我的 XSL:
<!DOCTYPE xsl:stylesheet [
<!ENTITY nl "
"> <!--new line CR, LF, or LF, your choice -->
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:key name='compspec' match="comp" use="partnumber" />
<xsl:template match="/components">
<xsl:for-each select="comp[generate-id(.)=generate-id(key('compspec',partnumber)[1])]">
<xsl:sort select="ref"/>
<xsl:for-each select="key('compspec',partnumber)">
<xsl:sort select="ref"/>
<xsl:value-of select="ref"/>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:text>,</xsl:text>
<xsl:value-of select="partnumber"/>
<xsl:text>&nl;</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我明白为什么我得到这个序列,但我对 XSLT 很陌生,我不知道如何修复它。我应该在我的代码中修复什么?我正在使用 XSLT 1.0。谢谢!
如果删除此行,您将获得所需的输出:
<xsl:sort select="partnumber"/>
在您的第一个 for-each
循环中,因为您按 partnumber
(bar
和 foo
)的字母顺序排序。
I need to sort groups with equal part number by minimum value of
comp/ref
要在 XSLT 1.0 中执行此操作,您必须进行两次传递:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name='compspec' match="comp" use="partnumber" />
<xsl:template match="/components">
<!-- first pass -->
<xsl:variable name="groups">
<xsl:for-each select="comp[generate-id(.)=generate-id(key('compspec',partnumber)[1])]">
<group name="{partnumber}">
<xsl:for-each select="key('compspec', partnumber)">
<xsl:sort select="ref"/>
<value>
<xsl:value-of select="ref"/>
</value>
</xsl:for-each>
</group>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<xsl:for-each select="exsl:node-set($groups)/group">
<xsl:sort select="value[1]"/>
<xsl:for-each select="value">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注:
在您的示例中,ref
包含文本值,在上面的代码中它被排序为 作为文本 。因此,comp/ref的最小值实际上是第一个ref
值.
我有一个 XML 文件如下所示:
<components>
<comp>
<ref>q7</ref>
<partnumber>foo</partnumber>
</comp>
<comp>
<ref>q1</ref>
<partnumber>foo</partnumber>
</comp>
<comp>
<ref>q6</ref>
<partnumber>bar</partnumber>
</comp>
<comp>
<ref>q3</ref>
<partnumber>bar</partnumber>
</comp>
</components>
而且我需要按零件号组合并按参考号排序,这样输出文件将如下所示:
q1 q7, foo
q3 q6, bar
但我得到了这个输出:
q3 q6, bar
q1 q7, foo
这是我的 XSL:
<!DOCTYPE xsl:stylesheet [
<!ENTITY nl "
"> <!--new line CR, LF, or LF, your choice -->
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:key name='compspec' match="comp" use="partnumber" />
<xsl:template match="/components">
<xsl:for-each select="comp[generate-id(.)=generate-id(key('compspec',partnumber)[1])]">
<xsl:sort select="ref"/>
<xsl:for-each select="key('compspec',partnumber)">
<xsl:sort select="ref"/>
<xsl:value-of select="ref"/>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:text>,</xsl:text>
<xsl:value-of select="partnumber"/>
<xsl:text>&nl;</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我明白为什么我得到这个序列,但我对 XSLT 很陌生,我不知道如何修复它。我应该在我的代码中修复什么?我正在使用 XSLT 1.0。谢谢!
如果删除此行,您将获得所需的输出:
<xsl:sort select="partnumber"/>
在您的第一个 for-each
循环中,因为您按 partnumber
(bar
和 foo
)的字母顺序排序。
I need to sort groups with equal part number by minimum value of comp/ref
要在 XSLT 1.0 中执行此操作,您必须进行两次传递:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name='compspec' match="comp" use="partnumber" />
<xsl:template match="/components">
<!-- first pass -->
<xsl:variable name="groups">
<xsl:for-each select="comp[generate-id(.)=generate-id(key('compspec',partnumber)[1])]">
<group name="{partnumber}">
<xsl:for-each select="key('compspec', partnumber)">
<xsl:sort select="ref"/>
<value>
<xsl:value-of select="ref"/>
</value>
</xsl:for-each>
</group>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<xsl:for-each select="exsl:node-set($groups)/group">
<xsl:sort select="value[1]"/>
<xsl:for-each select="value">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>, </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注:
在您的示例中,ref
包含文本值,在上面的代码中它被排序为 作为文本 。因此,comp/ref的最小值实际上是第一个ref
值.