Обычно, если вы хотите найти отдельные элементы, вы можете рассматривать это как проблему группировки, но вам нужно вывести только одно значение из каждой группы. В XSLT 1.0 вы будете использовать технику под названием Muenchian Grouping , что будет означать определение ключа следующим образом:
<xsl:key name="orders" match="Order" use="Delivery" />
Однако у вас есть дополнительная сложность получения последнего заказа по дате. Вероятно, самый простой вариант - создать переменную, содержащую только последние Order
элементов для каждого OrderHistory
<xsl:variable name="Orders">
<xsl:for-each select="//Book[status = 'In Stock']/OrderHistory">
<xsl:for-each select="Order">
<xsl:sort select="date" order="descending" />
<xsl:if test="position() = 1">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
Однако вам нужно использовать функцию расширения, чтобы преобразовать этот «Фрагмент дерева результатов» в набор узлов, который затем вы можете использовать технику группирования Мюнцзяня. Больше всего похоже, что ваш процесс поддерживает EXSLT, что означает добавление этого пространства имен
xmlns:exsl="http://exslt.org/common"
Затем, чтобы получить различные значения из переменной, вы делаете это ...
<xsl:for-each select="exsl:node-set($Orders)/Order[generate-id() = generate-id(key('orders', Delivery)[1])]">
Попробуйте это XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
version="1.0">
<xsl:output method="text" />
<xsl:key name="orders" match="Order" use="Delivery" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="Orders">
<xsl:for-each select="//Book[status = 'In Stock']/OrderHistory">
<xsl:for-each select="Order">
<xsl:sort select="date" order="descending" />
<xsl:if test="position() = 1">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="exsl:node-set($Orders)/Order[generate-id() = generate-id(key('orders', Delivery)[1])]">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="Delivery" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
См. Это в действии на http://xsltfiddle.liberty -development.net / 3NzcBtu / 2 (который использует Microsoft XSLTCompiledTransform, то есть XSLT 1.0).
В идеале, вам стоит подумать об обновлении до XSLT 3.0, чтобы не скучать с Мартином Хонненом ...