xml - 即使缺少分组键,也可以在 XSLT 中对元素进行分组
问题描述
我有以下 XML:
<cars>
<car type='toyota'>
<model>Yaris</model>
<year>1998</year>
<company>TOYOTA</company>
</car>
<car type='kia'>
<model>Optima</model>
<year>2002</year>
<company>KIA</company>
</car>
<car type='kia'>
<model>CERATO</model>
<year>2009</year>
<company>KIA</company>
</car>
<car type='bmw'>
<model>M3</model>
<year>2016</year>
<company>BMW</company>
</car>
<car type='bmw'>
<model>X5</model>
<year>2010</year>
</car>
<car type='bmw'>
<model>335i</model>
<year>2010</year>
<company>BMW</company>
</car>
</cars>
我想按公司元素对汽车进行分组,并在同一元素上进行排序(alpha,升序)。输出应该是这样的:
BMW: M3, X5, 335i
KIA: Optima, CERATO
TOYOTA: Yaris
问题是 car 元素可能不包含公司节点,在这种情况下,必须使用 car/@type 值将元素添加到正确的组中。如何将@type 属性的值映射到基于公司价值的正确组?
解决方案
XSLT 的一个鲜为人知的特性(至少在 2.0 版中)是,当您创建一个列表时,例如(xx, yy, zz)
,这个列表实际上只包含现有值。如果例如xx
value 为空,则它将不是结果列表的一部分。
所以如果你[1]
在它后面写,你实际上是从括号之间的表达式列表中得到第一个非空元素。
在您的评论中,从 5.08 开始,您要求提供一个other
类型应该被视为TOYOTA
. if ... then ... else ...
在这种情况下
,可以使用,: if (@type = 'other') then 'TOYOTA' else @type
因此,您可以通过以下方式编写脚本:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="cars">
<xsl:for-each-group select="car" group-by="upper-case(
(company, if (@type = 'other') then 'TOYOTA' else @type)[1])">
<xsl:sort select="current-grouping-key()"/>
<xsl:value-of select="current-grouping-key()"/>
<xsl:text>: </xsl:text>
<xsl:value-of select="string-join(current-group()/model, ', ')"/>
<xsl:text>
</xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:transform>
如你看到的:
(company, if (@type = 'other') then 'TOYOTA' else @type)
是源列表(大写的参数),[1]
从已创建的内容中获取第一个元素。
我将调用移至upper-case
“外层”,假设model
也可以用小写字母编写。
推荐阅读
- vue.js - Vue js - 根据当前时间显示列表中的元素
- amazon-web-services - 当我没有超过免费套餐限制时,为什么我的 aws starter 帐户免费积分会被使用?
- c++ - 在移动蛇头的同时不断更新屏幕,直到我们得到输入
- php - 如何在 Codeigniter 4 控制器中使电子邮件字段可选
- css - CSS nth-chid 选择器没有隐藏的冷节点
- python - tkinter中的PNG图像透明度
- node.js - Electron App 打包后没有运行
- python-3.x - pyautogui 不在文本字段中写入 Excel 单元格内容
- python - 我似乎无法在 python 3 中找到数字的最高素数的正确代码
- javafx - 在按钮上显示“stage2”后如何隐藏“stage1”单击[JavaFX]