Muenchian Method在Altova XMLSpy中无法按门店分组容器ID
Muenchian分组失效问题分析及修复
问题背景
尝试使用XSLT 1.0的Muenchian方法,将XML中的container_id按store编号分组,但未得到预期结果:每个唯一门店编号重复出现,且barcode无法正确映射对应门店的container_id值。
输入XML
<D856s> <D856> <container_id>1234</container_id> <trip_no>15</trip_no> <store>5</store> <description>description1</description> </D856> <D856> <container_id>9956</container_id> <trip_no>18</trip_no> <store>4</store> <description>description2</description> </D856> <D856> <container_id>5566</container_id> <trip_no>20</trip_no> <store>4</store> <description>description3</description> </D856> <D856> <container_id>2233</container_id> <trip_no>19</trip_no> <store>5</store> <description>description4</description> </D856> <D856> <container_id>1122</container_id> <trip_no>12</trip_no> <store>2</store> <description>description5</description> </D856> </D856s>
错误的XSLT 1.0代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="D856s"/> </xsl:template> <xsl:key name="groupByStore" use="D856" match="store"/> <xsl:template match="D856s"> <xsl:for-each select="D856[count(. | key('groupByStore', store)[1]) = 1]"> <xsl:sort select="store"/> <StoreNum> <xsl:value-of select="store"/> </StoreNum> <barcode> <xsl:for-each select="key('groupByStore', store)"> <xsl:sort select="container_id"/> <xsl:value-of select="container_id"/> </xsl:for-each> </barcode> </xsl:for-each> </xsl:template> </xsl:stylesheet>
问题原因分析
核心错误出在**xsl:key的定义上**,直接导致分组逻辑完全失效:
match和use属性颠倒:正确的Muenchian分组应该用match指定要分组的节点(此处为D856),用use指定分组依据的节点值(此处为store)。原代码中match="store"、use="D856"完全搞反,导致key实际存储的是store节点,而非D856节点。- 分组判断逻辑失效:因为key定义错误,
key('groupByStore', store)返回的是所有与当前store值匹配的store节点,而非D856节点。因此count(. | key('groupByStore', store)[1]) = 1的判断无法筛选出唯一的分组节点,每个D856都会被当成独立分组,导致门店编号重复出现。 container_id取值错误:遍历key('groupByStore', store)时,当前节点是store节点,而非D856节点,自然无法取到同级的container_id值。
修复后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 正确定义key:按store值分组D856节点 --> <xsl:key name="groupByStore" match="D856" use="store"/> <xsl:template match="/"> <xsl:apply-templates select="D856s"/> </xsl:template> <xsl:template match="D856s"> <!-- 筛选每个store分组的第一个D856节点 --> <xsl:for-each select="D856[count(. | key('groupByStore', store)[1]) = 1]"> <xsl:sort select="store" data-type="number"/> <StoreNum> <xsl:value-of select="store"/> </StoreNum> <barcode> <!-- 遍历当前store分组下的所有D856节点 --> <xsl:for-each select="key('groupByStore', store)"> <xsl:sort select="container_id" data-type="number"/> <!-- 此处当前节点是D856,可直接取container_id --> <xsl:value-of select="container_id"/> <!-- 可选:添加分隔符区分多个container_id --> <xsl:if test="position() != last()">, </xsl:if> </xsl:for-each> </barcode> </xsl:for-each> </xsl:template> </xsl:stylesheet>
预期输出
<?xml version="1.0" encoding="UTF-8"?> <StoreNum>2</StoreNum> <barcode>1122</barcode> <StoreNum>4</StoreNum> <barcode>5566, 9956</barcode> <StoreNum>5</StoreNum> <barcode>1234, 2233</barcode>
内容的提问来源于stack exchange,提问作者PurpleSkittles
相关产品推荐
相关产品推荐

