Я хочу получить узлы из набора узлов, которые не включены в другой набор узлов.
первый набор узлов
<suppressingEvent event="x">
<suppressedEvent event="a"/>
<suppressedEvent event="b"/>
<suppressedEvent event="c"/>
</suppressingEvent>
второй набор узлов
<suppressingEvent event="y">
<suppressedEvent event="a"/>
<suppressedEvent event="b"/>
<suppressedEvent event="c"/>
<suppressedEvent event="d"/>
</suppressingEvent>
Таким образом Я хочу получить <suppressedEvent event="d"/>
Сначала я фильтрую второй набор узлов для suppressedEvent
узлов первого набора узлов с помощью ключа и сохраняю их в переменной sameSuppressedEvents
.
<xsl:variable name="sameSuppressedEvents" select="key('suppressedEventsFromSuppressingEvent', $suppressingEvent/suppressedEvent/@event, .)"/>
* 1016. * Затем я хочу сохранить оставшиеся
<suppressedEvent event="d"/>
в переменной
otherSuppressedEvents
. Но предикат
[not($sameSuppressedEvents)]
не работает.
<xsl:variable name="otherSuppressedEvents" select="./suppressedEvent[not($sameSuppressedEvents)]"/>
Но когда я использую непосредственно ключ внутри предиката, я получаю желаемый результат.
<xsl:variable name="otherSuppressedEvents" select="./suppressedEvent[not(key('suppressedEventsFromSuppressingEvent', $suppressingEvent/suppressedEvent/@event, .))]"/>
Почему он ведет себя так ?
А что на самом деле делает <xsl:variable name="otherSuppressedEvents" select="./suppressedEvent[not($sameSuppressedEvents)]"/>
? Очевидно, что не возвращаются неравные suppressedEvent
узлы.
Существует ли общий способ сравнения двух переменных, которые содержат набор узлов и возвращают только те узлы, которые являются уникальными в исследуемом наборе узлов?
Полная таблица стилей
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" media-type="application/xml" encoding="UTF-8" standalone="no"/>
<xsl:template match="/">
<FIDandFIC>
<xsl:apply-templates select="FiMrelations/suppressingEvent"/>
</FIDandFIC>
</xsl:template>
<xsl:template match="suppressingEvent">
<FIC>
<xsl:attribute name="event">
<xsl:value-of select="./@event"/>
</xsl:attribute>
<xsl:attribute name="fatal">
<xsl:value-of select="./@fatal"/>
</xsl:attribute>
<!-- Take all other suppressingEvent nodes to compare the underlying suppressedEvent Nodes with the ones from this current suppressingEvent -->
<!-- If the underlying suppressed Events are the same then you can combine these suppressing Events to one FID -->
<xsl:apply-templates select="../suppressingEvent" mode="equalFID">
<xsl:with-param name="suppressingEvent" select="."/>
</xsl:apply-templates>
</FIC>
</xsl:template>
<xsl:key name="suppressedEventsFromSuppressingEvent" match="suppressedEvent" use="./@event"/>
<xsl:template match="suppressingEvent" mode="equalFID">
<xsl:param name="suppressingEvent"/>
<xsl:if test="count($suppressingEvent/suppressedEvent) = count(./suppressedEvent)">
<xsl:variable name="sameSuppressedEvents" select="key('suppressedEventsFromSuppressingEvent', $suppressingEvent/suppressedEvent/@event, .)"/>
<xsl:variable name="otherSuppressedEvents" select="./suppressedEvent[not(key('suppressedEventsFromSuppressingEvent', $suppressingEvent/suppressedEvent/@event, .))]"/>
<!-- this does not work -->
<!-- <xsl:variable name="otherSuppressedEvents" select="./suppressedEvent[not($sameSuppressedEvents)]"/> -->
<xsl:if test="not($otherSuppressedEvents)">
<equalFID>
<xsl:attribute name="suppressingEvent">
<xsl:value-of select="./@event"/>
</xsl:attribute>
<xsl:attribute name="OBD-Relevant">
<xsl:value-of select="./@OBD-Relevant"/>
</xsl:attribute>
<xsl:attribute name="fatal">
<xsl:value-of select="./@fatal"/>
</xsl:attribute>
</equalFID>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>