xslt - 如何遍历节点并跳过具有相同值的重复节点 - XSLT 1,0
问题描述
我有一个类似的xml,
<DESIGN-FUNCTION-PROTOTYPE>
<SHORT-NAME>xxx</SHORT-NAME>
<TYPE-TREF TYPE="DESIGN-FUNCTION-PROTOTYPE">ABC/DEF/123</TYPE-TREF>
</DESIGN-FUNCTION-PROTOTYPE>
<DESIGN-FUNCTION-PROTOTYPE>
<SHORT-NAME>yyy</SHORT-NAME>
<TYPE-TREF TYPE="DESIGN-FUNCTION-PROTOTYPE">LMN/OPQ/123</TYPE-TREF>
</DESIGN-FUNCTION-PROTOTYPE>
<DESIGN-FUNCTION-PROTOTYPE>
<SHORT-NAME>mmm</SHORT-NAME>
<TYPE-TREF TYPE="DESIGN-FUNCTION-PROTOTYPE">XYZ/GHY/456</TYPE-TREF>
</DESIGN-FUNCTION-PROTOTYPE>
<DESIGN-FUNCTION-PROTOTYPE>
<SHORT-NAME>nnn</SHORT-NAME>
<TYPE-TREF TYPE="DESIGN-FUNCTION-PROTOTYPE">AJK/UTL/456</TYPE-TREF>
</DESIGN-FUNCTION-PROTOTYPE>
我的xslt,
<xsl:template name="substring-after-last">
<xsl:param name="string" />
<xsl:param name="delimiter" />
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string"
select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiter" select="$delimiter" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:for-each select="select="//DESIGN-FUNCTION-PROTOTYPE/ea:TYPE-TREF[@TYPE='DESIGN-FUNCTION-TYPE']">
<xsl:variable name="myVar" select="current()"/>
<xsl:variable name="taskName" select="../ea:SHORT-NAME"/>
<xsl:variable name="Var7">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string" select="$myVar" />
<xsl:with-param name="delimiter" select="'/'" />
</xsl:call-template>
</xsl:variable>
<varoutput>
<xsl:value-of select="$Var7"/>
</varoutput>
</xsl:for-each>
我的意图是迭代所有“DESIGN-FUNCTION-PROTOTYPE”元素并显示“TYPE-TREF”值的子字符串,但如果已经读取了“TYPE-TREF”值的子字符串..i必须跳过该元素。
预期输出,
123
456
并不是,
123
123
456
456
一般来说,我应该只考虑第一次出现并跳过其余的。
解决方案
您可以使用Muenchian Grouping技术实现此目的,该技术是XSLT-1.0 的分组方法。
以下代码示例实现了它以整理出双峰:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:key name="proto" match="DESIGN-FUNCTION-PROTOTYPE" use="TYPE-TREF" />
<xsl:template match="/">
<xsl:for-each select="//DESIGN-FUNCTION-PROTOTYPE[generate-id() = generate-id(key('proto',TYPE-TREF)[1])]">
<varoutput>
<xsl:value-of select="TYPE-TREF"/>
</varoutput>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
它的输出是:
<varoutput>ABC</varoutput>
<varoutput>XYZ</varoutput>
您现在不同的问题的答案,实施相同的技术,可以是
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:key name="proto" match="DESIGN-FUNCTION-PROTOTYPE" use="substring-after(substring-after(TYPE-TREF,'/'),'/')" />
<xsl:template match="/">
<xsl:for-each select="//DESIGN-FUNCTION-PROTOTYPE[generate-id() = generate-id(key('proto',substring-after(substring-after(TYPE-TREF,'/'),'/'))[1])]">
<xsl:value-of select="substring-after(substring-after(TYPE-TREF,'/'),'/')"/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
它的输出是:
123
456
请注意,SO规则不赞成在合适的答案后大幅改变问题。别再那么做了。
推荐阅读
- xml - 真值计数器 XML
- c# - OpenQA.Selenium.ElementNotInteracable - 无法到达元素
- python - Daphne 和 Systemd:将文件描述符传递给子进程
- vb.net - 如何将数据集对象转换为列表
在 vb.net - linux - 无法远程连接到 svnserver
- c# - 带有参数的 Entity Framework Core 事务
- javascript - 如何使用并检查此javascript代码中的其他条件以从服务器端回显按钮推送或弹出?
- javascript - Javascript:在段落内动态添加粗体文本
- python - 在 Django 中渲染一个简单的复选框的麻烦
- scala - 在 scala maps/trie maps 中存储类实例