我的输入XML。
<?xml version="1.0" encoding="iso-8859-1"?>
<results>
<result>
<Store>0180|1</Store>
</result>
<result>
<Store>0180|2</Store>
</result>
<result>
<Store>0181</Store>
</result>
<result>
<Store>0183</Store>
</result>
<result>
<Store>abc</Store>
</result>
<result>
<Store>def</Store>
</result>
<result>
<Store>0181|2</Store>
</result>
<result>
<Store>0180|3</Store>
</result>
<result>
<Store>0181|1</Store>
</result>
</results>
Xslt if fix = p then substring-before否则substring-after on key:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="name" select="'|'"/>
<xsl:param name="fix" select="'p'"/>
<xsl:choose>
<xsl:when fix='p'>
<xsl:key name="groups" match="/results/result" use="substring-before(Store,'|')" />
</xsl:when>
<otherwise>
<xsl:key name="groups" match="/results/result" use="substring-after(Store,'|')" />
</otherwise>
</xsl:choose>
<
<xsl:template match="/results">
<xsl:choose>
<xsl:when test="$fix='p'">
<xsl:apply-templates select="result[generate-id() = generate-id(key('groups', substring-before(Store,'|'))[1])]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="result[generate-id() = generate-id(key('groups', substring-after(Store,'|'))[1])]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="result">
<xsl:choose>
<xsl:when test="$fix='p'">
<xsl:for-each select="key('groups', substring-before(Store,'|'))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-before(Store,'|')"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="Store"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="key('groups', substring-before(Store,'|'))">
<xsl:choose>
<xsl:when test="contains(Store,'|')">
<td>
<xsl:value-of select="substring-after(Store,'|')"/>
<xsl:value-of select="'|'"/>
<xsl:value-of select="position()"/>
</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="Store"/>
</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
xsl:key
定义必须位于样式表的顶层
相反,xsl:choose
不能处于最高级别。
以此为出发点;
XSLT 1.0
<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"/>
<xsl:strip-space elements="*"/>
<xsl:param name="key-direction" select="'before'"/>
<xsl:key name="key-before" match="result" use="substring-before(Store, '|')"/>
<xsl:key name="key-after" match="result" use="substring-after(Store, '|')"/>
<xsl:template match="/results">
<xsl:copy>
<xsl:choose>
<xsl:when test="$key-direction='before'">
<xsl:apply-templates select="result[generate-id()=generate-id(key('key-before', substring-before(Store,'|'))[1])]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="result[generate-id() = generate-id(key('key-after', substring-after(Store,'|'))[1])]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<!-- more templates -->
</xsl:stylesheet>
另请注意:
substring-before('abc', '|')
返回一个空字符串。这意味着:
<Store>0181</Store>
和
<Store>0181|1</Store>
不会被组合在一起,除非您替换:
substring-before(Store, '|')
使用:
substring-before(concat(Store, '|'), '|')