Xml 使用XSLT对数据进行分组并不完全有效
我创建了一个XSLT,用于对鞋子目录的数据进行分组。鞋子需要按“线”和“品牌”进行分组。行和品牌名称需要出现在每个部分的开头。每条生产线都有多个品牌。每个品牌通常都有不止一只鞋 以下是一些示例XML数据:Xml 使用XSLT对数据进行分组并不完全有效,xml,xslt,Xml,Xslt,我创建了一个XSLT,用于对鞋子目录的数据进行分组。鞋子需要按“线”和“品牌”进行分组。行和品牌名称需要出现在每个部分的开头。每条生产线都有多个品牌。每个品牌通常都有不止一只鞋 以下是一些示例XML数据: <?xml version="1.0" encoding="UTF-8"?> <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <shoe> <line>LIN
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<shoe>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brand>WALKING</brand>
<style-name>NEW BALANCE-NB 475V2 (WIDE)</style-name>
<color>Black</color>
<price>67.99</price>
</shoe>
<shoe>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brand>WALKING</brand>
<style-name>NEW BALANCE-496 (WIDE)</style-name>
<color>Grey/Pink</color>
<price>64.99</price>
</shoe>
<shoe>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brand>CROSS TRANING</brand>
<style-name>FILA-MEMORY PANACHE</style-name>
<color>Black/Pink</color>
<price>69.99</price>
</shoe>
<shoe>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brand>RUNNING</brand>
<style-name>FILA-VITALITY 2 TRAIL</style-name>
<color>Grey/Prpl/Turq</color>
<price>59.99</price>
</shoe>
<shoe>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brand>CASUAL</brand>
<style-name>LEVI'S-HAMILTON BUCK HI</style-name>
<color>Black/Black</color>
<price>34.99</price>
</shoe>
<shoe>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brand>CASUAL</brand>
<style-name>EVERLAST-EVAN SKATE</style-name>
<color>Black</color>
<price>29.99</price>
</shoe>
<shoe>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brand>RUNNING</brand>
<style-name>SKECHERS-POWER SWITCH (WIDE)</style-name>
<color>Black/White</color>
<price>69.99</price>
</shoe>
<shoe>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brand>RUNNING</brand>
<style-name>SKECHERS-EQUALIZER GEL TOP </style-name>
<color>Black</color>
<price>69.99</price>
</shoe>
</catalog>
第43行:女性品牌运动鞋
行走
新天平-NB 475V2(宽)
黑色
67.99
第43行:女性品牌运动鞋
行走
新余额-496(宽)
灰色/粉红色
64.99
第43行:女性品牌运动鞋
交叉训练
FILA-MEMORY华丽
黑色/粉红色
69.99
第43行:女性品牌运动鞋
跑步
菲拉2号小径
灰色/Prpl/Turq
59.99
第87行:男士品牌运动鞋
随便的
李维斯汉密尔顿巴克你好
黑色/黑色
34.99
第87行:男士品牌运动鞋
随便的
EVERLAST-EVAN滑板
黑色
29.99
第87行:男士品牌运动鞋
跑步
SKECHERS-电源开关(宽)
黑/白
69.99
第87行:男士品牌运动鞋
跑步
SKECHERS-EQUALIZER凝胶顶部
黑色
69.99
这是我的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="shoes-by-line" match="shoe" use="line" />
<xsl:key name="shoes-by-brand" match="shoe" use="concat(line,'#',brand )" />
<xsl:template match="catalog">
<catalog>
<shoes>
<xsl:for-each select="shoe[count(. | key('shoes-by-line', line)[1]) = 1]">
<line>
<xsl:value-of select="line"/>
</line>
<brands>
<brand>
<xsl:value-of select="brand"/>
</brand>
<xsl:for-each select="key( 'shoes-by-brand', concat(line,'#',brand ))">
<shoe>
<style-name>
<xsl:value-of select="style-name"/>
</style-name>
<color>
<xsl:value-of select="color"/>
</color>
<price>
<xsl:value-of select="price"/>
</price>
</shoe>
</xsl:for-each>
</brands>
</xsl:for-each>
</shoes>
</catalog>
</xsl:template>
</xsl:stylesheet>
我得到了一个“线”和一个“品牌”,但我没有在每一行得到额外的品牌。每条生产线至少应有两到三个品牌。在这个XML中有两行
以下是我想要的XML结构:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>WALKING</brand>
<shoes>
<shoe>
<style-name>NEW BALANCE-NB 475V2 (WIDE)</style-name>
<color>Black</color>
<price>67.99</price>
</shoe>
<shoe>
<style-name>NEW BALANCE-496 (WIDE)</style-name>
<color>Grey/Pink</color>
<price>64.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>CROSS TRANING</brand>
<shoes>
<shoe>
<style-name>FILA-MEMORY PANACHE</style-name>
<color>Black/Pink</color>
<price>69.99</price>
</shoe>
<shoe>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brand>RUNNING</brand>
<style-name>FILA-VITALITY 2 TRAIL</style-name>
<color>Grey/Prpl/Turq</color>
<price>59.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>CASUAL</brand>
<shoes>
<shoe>
<style-name>LEVI'S-HAMILTON BUCK HI</style-name>
<color>Black/Black</color>
<price>34.99</price>
</shoe>
<shoe>
<style-name>EVERLAST-EVAN SKATE</style-name>
<color>Black</color>
<price>29.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<style-name>SKECHERS-POWER SWITCH (WIDE)</style-name>
<color>Black/White</color>
<price>69.99</price>
</shoe>
<shoe>
<style-name>SKECHERS-EQUALIZER GEL TOP </style-name>
<color>Black</color>
<price>69.99</price>
</shoe>
</shoes>
</brands>
</lines>
</catalog>
第43行:女性品牌运动鞋
行走
新天平-NB 475V2(宽)
黑色
67.99
新余额-496(宽)
灰色/粉红色
64.99
第43行:女性品牌运动鞋
交叉训练
FILA-MEMORY华丽
黑色/粉红色
69.99
第43行:女性品牌运动鞋
跑步
菲拉2号小径
灰色/Prpl/Turq
59.99
第87行:男士品牌运动鞋
随便的
李维斯汉密尔顿巴克你好
黑色/黑色
34.99
EVERLAST-EVAN滑板
黑色
29.99
第87行:男士品牌运动鞋
跑步
第87行:男士品牌运动鞋
跑步
SKECHERS-电源开关(宽)
黑/白
69.99
SKECHERS-EQUALIZER凝胶顶部
黑色
69.99
对XSLT进行一些调整后,将生成所需的结果:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="shoes-by-line" match="shoe" use="line" />
<xsl:key name="shoes-by-brand" match="shoe" use="concat(line,'#',brand )" />
<xsl:template match="catalog">
<catalog>
<xsl:for-each select="shoe[count(. | key('shoes-by-line', line)[1]) = 1]">
<lines>
<line>
<xsl:value-of select="line"/>
</line>
<brands>
<brand>
<xsl:value-of select="brand"/>
</brand>
<shoes>
<xsl:for-each select="key( 'shoes-by-brand', concat(line,'#',brand ))">
<shoe>
<style-name>
<xsl:value-of select="style-name"/>
</style-name>
<color>
<xsl:value-of select="color"/>
</color>
<price>
<xsl:value-of select="price"/>
</price>
</shoe>
</xsl:for-each>
</shoes>
</brands>
</lines>
</xsl:for-each>
</catalog>
</xsl:template>
</xsl:stylesheet>
应用于输入XML时,会产生以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>WALKING</brand>
<shoes>
<shoe>
<style-name>NEW BALANCE-NB 475V2 (WIDE)</style-name>
<color>Black</color>
<price>67.99</price>
</shoe>
<shoe>
<style-name>NEW BALANCE-496 (WIDE)</style-name>
<color>Grey/Pink</color>
<price>64.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>CROSS TRANING</brand>
<shoes>
<shoe>
<style-name>FILA-MEMORY PANACHE</style-name>
<color>Black/Pink</color>
<price>69.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<style-name>FILA-VITALITY 2 TRAIL</style-name>
<color>Grey/Prpl/Turq</color>
<price>59.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>CASUAL</brand>
<shoes>
<shoe>
<style-name>LEVI'S-HAMILTON BUCK HI</style-name>
<color>Black/Black</color>
<price>34.99</price>
</shoe>
<shoe>
<style-name>EVERLAST-EVAN SKATE</style-name>
<color>Black</color>
<price>29.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<style-name>SKECHERS-POWER SWITCH (WIDE)</style-name>
<color>Black/White</color>
<price>69.99</price>
</shoe>
<shoe>
<style-name>SKECHERS-EQUALIZER GEL TOP </style-name>
<color>Black</color>
<price>69.99</price>
</shoe>
</shoes>
</brands>
</lines>
</catalog>
第43行:女性品牌运动鞋
行走
新天平-NB 475V2(宽)
黑色
67.99
新余额-496(宽)
灰色/粉红色
64.99
第43行:女性品牌运动鞋
交叉训练
FILA-MEMORY华丽
黑色/粉红色
69.99
第43行:女性品牌运动鞋
跑步
菲拉2号小径
灰色/Prpl/Turq
59.99
第87行:男士品牌运动鞋
随便的
李维斯汉密尔顿巴克你好
黑色/黑色
34.99
EVERLAST-EVAN滑板
黑色
29.99
第87行:男士品牌运动鞋
跑步
SKECHERS-电源开关(宽)
黑/白
69.99
SKECHERS-EQUALIZER凝胶顶部
黑色
69.99
请注意,与OP中给出的请求输出有一个不同之处-第43行的品牌RUNNING
:女子品牌田径是一个单独的品牌,而不是交叉训练
品牌,但这可能是所需输出中的一个小错误。否则,必须找到解决方案,使运行
和交叉培训
列在同一品牌中
由于应为每条生产线的每个品牌列出鞋款,
首先选择按生产线分组的所有鞋款。然后,使用
按品牌选择该组中的所有品牌,并在循环中处理该品牌的所有鞋子
更新:如评论中所述,这是一个XSLT 2.0样式表。我刚刚更正了上面模板中的版本。虽然我已经使用在线XSLT测试工具测试了该模板,并将其声明为1.0版,但它没有抛出任何错误(尽管它应该有) 我重温了XSLT,我相信我找到了使用XSLT1.0的解决方案
<?xml version="1.0" encoding="UTF-8"?><!-- DWXMLSource="D76-shoebook.xml" -->
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="shoes-by-line" match="shoe" use="line"/>
<xsl:key name="shoes-by-brand" match="shoe" use="concat(line, '|', brand)"/>
<xsl:template match="catalog">
<catalog>
<xsl:for-each select="shoe[generate-id() = generate-id(key('shoes-by-line', line)[1])]">
<lines>
<xsl:for-each select="key('shoes-by-line', line)[generate-id() = generate-id(key('shoes-by-brand', concat(line, '|', brand))[1])]">
<line><xsl:value-of select="line"/></line><xsl:text>
</xsl:text><brand><xsl:value-of select="brand"/></brand><xsl:text>
</xsl:text><shoes>
<xsl:for-each select="key('shoes-by-brand', concat(line, '|', brand))">
<shoe>
<style-name><xsl:value-of select="style-name" /></style-name>
<color><xsl:value-of select="color" /></color><xsl:text>
<price><xsl:value-of select="price" /></price><xsl:text>
</xsl:text>
</shoe>
</xsl:for-each>
</shoes>
</xsl:for-each>
</lines>
</xsl:for-each>
</catalog>
</xsl:template>
</xsl:stylesheet>
这将从离线和在线的源XML键控生成适当的分组和嵌套 在我看来,如果您添加了对所做调整的解释,您的答案可能会有很大的改进。@MathiasMüller感谢您的关注,我现在添加此内容是因为我同意您的观点,也不喜欢只提供代码答案(尽管此处的调整很小)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="catalog">
<catalog>
<xsl:for-each-group select="shoe" group-by="line">
<xsl:for-each-group select="current-group()" group-by="brand">
<lines>
<line>
<xsl:value-of select="line"></xsl:value-of>
</line>
<brands>
<xsl:for-each-group select="current-group()" group-by="brand">
<brand>
<xsl:value-of select="current-grouping-key()"></xsl:value-of>
</brand>
<shoes>
<xsl:for-each select="current-group()">
<shoe>
<style-name>
<xsl:value-of select="style-name"/>
</style-name>
<color>
<xsl:value-of select="color"/>
</color>
<price>
<xsl:value-of select="price"/>
</price>
</shoe>
</xsl:for-each>
</shoes>
</xsl:for-each-group>
</brands>
</lines>
</xsl:for-each-group>
</xsl:for-each-group>
</catalog>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>WALKING</brand>
<shoes>
<shoe>
<style-name>NEW BALANCE-NB 475V2 (WIDE)</style-name>
<color>Black</color>
<price>67.99</price>
</shoe>
<shoe>
<style-name>NEW BALANCE-496 (WIDE)</style-name>
<color>Grey/Pink</color>
<price>64.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>CROSS TRANING</brand>
<shoes>
<shoe>
<style-name>FILA-MEMORY PANACHE</style-name>
<color>Black/Pink</color>
<price>69.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 43: WOMENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<style-name>FILA-VITALITY 2 TRAIL</style-name>
<color>Grey/Prpl/Turq</color>
<price>59.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>CASUAL</brand>
<shoes>
<shoe>
<style-name>LEVI'S-HAMILTON BUCK HI</style-name>
<color>Black/Black</color>
<price>34.99</price>
</shoe>
<shoe>
<style-name>EVERLAST-EVAN SKATE</style-name>
<color>Black</color>
<price>29.99</price>
</shoe>
</shoes>
</brands>
</lines>
<lines>
<line>LINE 87: MENS BRANDED ATHLETIC</line>
<brands>
<brand>RUNNING</brand>
<shoes>
<shoe>
<style-name>SKECHERS-POWER SWITCH (WIDE)</style-name>
<color>Black/White</color>
<price>69.99</price>
</shoe>
<shoe>
<style-name>SKECHERS-EQUALIZER GEL TOP </style-name>
<color>Black</color>
<price>69.99</price>
</shoe>
</shoes>
</brands>
</lines>
</catalog>
<?xml version="1.0" encoding="UTF-8"?><!-- DWXMLSource="D76-shoebook.xml" -->
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:key name="shoes-by-line" match="shoe" use="line"/>
<xsl:key name="shoes-by-brand" match="shoe" use="concat(line, '|', brand)"/>
<xsl:template match="catalog">
<catalog>
<xsl:for-each select="shoe[generate-id() = generate-id(key('shoes-by-line', line)[1])]">
<lines>
<xsl:for-each select="key('shoes-by-line', line)[generate-id() = generate-id(key('shoes-by-brand', concat(line, '|', brand))[1])]">
<line><xsl:value-of select="line"/></line><xsl:text>
</xsl:text><brand><xsl:value-of select="brand"/></brand><xsl:text>
</xsl:text><shoes>
<xsl:for-each select="key('shoes-by-brand', concat(line, '|', brand))">
<shoe>
<style-name><xsl:value-of select="style-name" /></style-name>
<color><xsl:value-of select="color" /></color><xsl:text>
<price><xsl:value-of select="price" /></price><xsl:text>
</xsl:text>
</shoe>
</xsl:for-each>
</shoes>
</xsl:for-each>
</lines>
</xsl:for-each>
</catalog>
</xsl:template>
</xsl:stylesheet>