XSLT: поведение key () внутри предиката - PullRequest
0 голосов
/ 01 мая 2020

Я хочу получить узлы из набора узлов, которые не включены в другой набор узлов.

первый набор узлов

<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>

1 Ответ

0 голосов
/ 01 мая 2020

Эффект функции key () с помощью «.» поскольку третий аргумент будет зависеть от значения «.», которое отличается внутри предиката, поэтому неудивительно, что два случая различны.

В первом случае вы не сказали нам что такое контекстный узел, когда вы вызываете key (). Во втором случае ясно, что это элемент suppressedEvent, что делает вызов очень сомнительным, так как key () будет искать только в поддереве с корнем в узле, указанном в третьем аргументе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...