如何在XSL中按序列顺序拼接消息?附XML示例需求
在XSL中按指定顺序拼接GiftMessage并填入CommentText节点
我来帮你搞定这个需求~咱们先明确目标:把属于同一个GiftWrapId和ClientIItemId的GiftMessage内容,按照GiftMessageSequence的数字顺序拼接成一个完整字符串,再把结果放到指定的CommentText节点里。
先看你的输入XML:
<Gifts> <Gift> <GiftWrapId>026272275</GiftWrapId> <ClientIItemId>191267166704</ClientIItemId> <GiftMessageSequence>1</GiftMessageSequence> <GiftMessageType>GIFT</GiftMessageType> <GiftMessage>Happy Birthday, sweet</GiftMessage> </Gift> <Gift> <GiftWrapId>026272275</GiftWrapId> <ClientIItemId>191267166704</ClientIItemId> <GiftMessageSequence>2</GiftMessageSequence> <GiftMessageType>GIFT</GiftMessageType> <GiftMessage>Konnie</GiftMessage> </Gift> </Gifts>
期望输出:
<CommentInfo> <CommentType>X</CommentType> <CommentText>Happy Birthday, sweet Konnie</CommentText> </CommentInfo>
解决方案(分XSLT版本)
1. XSLT 1.0 兼容版(适合大多数环境)
这个版本用分组键和排序来实现,兼容性拉满:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 用GiftWrapId+ClientIItemId拼接作为分组键,避免单一ID重复 --> <xsl:key name="giftGroup" match="Gift" use="concat(GiftWrapId, '|', ClientIItemId)"/> <xsl:template match="/"> <CommentInfo> <CommentType>X</CommentType> <CommentText> <!-- 取出当前分组的所有Gift节点,按Sequence数字排序 --> <xsl:for-each select="key('giftGroup', concat(Gift[1]/GiftWrapId, '|', Gift[1]/ClientIItemId))"> <xsl:sort select="GiftMessageSequence" data-type="number"/> <!-- 输出当前GiftMessage内容 --> <xsl:value-of select="GiftMessage"/> <!-- 最后一个节点后不加空格 --> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> </CommentText> </CommentInfo> </xsl:template> </xsl:stylesheet>
2. XSLT 2.0+ 简洁版
如果你的环境支持XSLT 2.0或更高版本,可以用更简洁的写法,利用内置的排序和分隔符属性:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <CommentInfo> <CommentType>X</CommentType> <CommentText> <!-- 筛选同组节点 → 按Sequence排序 → 提取GiftMessage并指定空格分隔 --> <xsl:value-of select=" Gift[concat(GiftWrapId, '|', ClientIItemId) = concat(/Gift[1]/GiftWrapId, '|', /Gift[1]/ClientIItemId)] /sort((.), function($g) {number($g/GiftMessageSequence)}) /GiftMessage" separator=" "/> </CommentText> </CommentInfo> </xsl:template> </xsl:stylesheet>
关键细节说明
- 分组逻辑:用
concat(GiftWrapId, '|', ClientIItemId)作为分组键,确保只有同时匹配两个ID的节点才会被分到同一组,避免单一ID重复导致的错误分组。 - 排序注意:一定要给
xsl:sort加上data-type="number"(XSLT1.0)或用number()转换(XSLT2.0+),不然会按字符串排序(比如数字10会排在2前面)。 - 空格处理:XSLT1.0里通过
position() != last()判断,避免末尾多出来的空格;XSLT2.0+直接用separator=" "就能自动处理分隔,更省心。
内容的提问来源于stack exchange,提问作者Aswin Francis
相关产品推荐
相关产品推荐

