Если вы хотите передать имена атрибутов в качестве параметра, то один подход может быть два шага преобразования, где первый шаг принимает любой ввод XML и просто имена атрибутов и имена элементов в качестве параметров для создания второй таблицы стилей, которая затем устраняет дубликаты. Вот пример первой таблицы стилей:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
exclude-result-prefixes="axsl exsl"
version="1.0">
<xsl:param name="parent-name" select="'items'"/>
<xsl:param name="element-name" select="'item'"/>
<xsl:param name="att-names" select="'att1,att2'"/>
<xsl:param name="sep" select="'|'"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="key-value">
<xsl:text>concat(</xsl:text>
<xsl:call-template name="define-values">
<xsl:with-param name="att-names" select="$att-names"/>
</xsl:call-template>
<xsl:text>)</xsl:text>
</xsl:variable>
<xsl:template name="define-values">
<xsl:param name="att-names"/>
<xsl:choose>
<xsl:when test="contains($att-names, ',')">
<xsl:value-of select="concat('@', substring-before($att-names, ','), ',"', $sep, '",')"/>
<xsl:call-template name="define-values">
<xsl:with-param name="att-names" select="substring-after($att-names, ',')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('@', $att-names)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<axsl:stylesheet version="1.0">
<axsl:output indent="yes"/>
<axsl:key name="k1" match="{$parent-name}/{$element-name}" use="{$key-value}"/>
<axsl:template match="@* | node()">
<axsl:copy>
<axsl:apply-templates select="@* | node()"/>
</axsl:copy>
</axsl:template>
<axsl:template match="{$parent-name}">
<axsl:copy>
<axsl:apply-templates select="@*"/>
<axsl:apply-templates select="{$element-name}[generate-id() = generate-id(key('k1', {$key-value})[1])]"/>
</axsl:copy>
</axsl:template>
</axsl:stylesheet>
</xsl:template>
</xsl:stylesheet>
Он принимает четыре параметра:
- : имя элемента, содержащего эти элементы которого вы хотите исключить дубликаты
element-name
: имя из тех элементов, из которых вы хотите удалить дубликаты
att-names
: список имен атрибутов, разделенных запятыми
sep
: разделитель символов, которые не должны возникать в значениях атрибутов во входном XML
Таблица стилей затем генерирует вторую таблицу стилей, которая применяется Muenchian группировку для устранения дубликатов. Например, с параметрами по умолчанию, указанными в таблице стилей Saxon 6.5.5 генерирует следующий таблицу стилей:
<axsl:stylesheet xmlns:axsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<axsl:output indent="yes"/>
<axsl:key name="k1" match="items/item" use="concat(@att1,"|",@att2)"/>
<axsl:template match="@* | node()">
<axsl:copy>
<axsl:apply-templates select="@* | node()"/>
</axsl:copy>
</axsl:template>
<axsl:template match="items">
<axsl:copy>
<axsl:apply-templates select="@*"/>
<axsl:apply-templates select="item[generate-id() = generate-id(key('k1', concat(@att1,"|",@att2))[1])]"/>
</axsl:copy>
</axsl:template>
</axsl:stylesheet>
Это может быть применен к документу XML, как
<items>
<item att1="a" att2="1" att3="A"/>
<item att1="b" att2="1" att3="A"/>
<item att1="a" att2="1" att3="B"/>
<item att1="c" att2="2" att3="A"/>
<item att1="d" att2="3" att3="C"/>
</items>
, а выход
<items>
<item att1="a" att2="1" att3="A"/>
<item att1="b" att2="1" att3="A"/>
<item att1="c" att2="2" att3="A"/>
<item att1="d" att2="3" att3="C"/>
</items>
Вы можете добавить пример xml и необходимый результат на свой вопрос – Treemonkey