xsl: если первый и последний узел не найден - PullRequest
0 голосов
/ 08 марта 2019

У меня есть XML в следующем виде:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ExistingReservations>
    <reservations>
        <reservation>
            <type>1</type>
            <start_time>2019-03-09T16:11:14Z</start_time>
            <stop_time>2019-03-09T16:23:23Z</stop_time>
        </reservation>
        <reservation>
            <type>2</type>
            <start_time>2019-03-09T11:23:12Z</start_time>
            <stop_time>2019-03-09T11:32:18Z</stop_time>
        </reservation>
        <reservation>
            <type>2</type>
            <start_time>2019-03-09T12:23:12Z</start_time>
            <stop_time>2019-03-09T12:32:18Z</stop_time>
        </reservation>
    </reservations>
</ExistingReservations>

Я хочу посмотреть только на резервирования типа '2', а затем получить диапазон дат.т.е. первое время начала и время последнего конца.

Но я борюсь с моим xsl, так как не могу получить первую и последнюю позиции.

Мой xsl выглядит следующим образом:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="ExistingReservations">
        <ReservationSchedule>
            <xsl:for-each select="//reservation">
                <xsl:if test="type='2'">
                    <period>
                        <xsl:if test="position()=1">
                            <start_time><xsl:value-of select="start_time"/><start_time>
                        </xsl:if>

                        <xsl:if test="position() = last()">
                            <end_time><xsl:value-of select="stop_time"/></end_time>
                        </xsl:if>

                    </period>
                </xsl:if>
            </xsl:for-each>
        </ReservationSchedule>
    </xsl:template>
</xsl:stylesheet>

Поэтому я хочу преобразовать в следующее:

<ReservationSchedule>
    <period>
        <start_time>2019-03-09T11:23:12Z</start_time>
        <end_time>2019-03-09T12:32:18Z</end_time>
    </period>
</ReservationSchedule>

Я думаю, что в <xsl:if test="position()=1"> не работает, потому что он смотрит на первый узел, который имеет тип 1 ..то есть это игнорирование логики <xsl:if test="type='2'">.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 08 марта 2019

Ваш xsl:for-each выбирает все резервирования, поэтому position() будет основываться на этом выбранном наборе узлов.xsl:if не повлияет на функцию position().

Что нужно сделать, это изменить сам оператор select, поэтому в первую очередь выбираются только резервирования типа 2

<xsl:template match="ExistingReservations">
    <ReservationSchedule>
        <xsl:for-each select="//reservation[type='2']">
            <period>
                <xsl:if test="position()=1">
                    <start_time><xsl:value-of select="start_time"/></start_time>
                </xsl:if>

                <xsl:if test="position() = last()">
                    <end_time><xsl:value-of select="stop_time"/></end_time>
                </xsl:if>
            </period>
        </xsl:for-each>
    </ReservationSchedule>
</xsl:template>

Кроме того, вы можете покончить с xsl:for-each и написать его так:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="ExistingReservations">
        <ReservationSchedule>
            <xsl:variable name="type2s" select="//reservation[type='2']" />
            <period>
                <start_time><xsl:value-of select="$type2s[1]/start_time"/></start_time>
                <end_time><xsl:value-of select="$type2s[last()]/stop_time"/></end_time>
            </period>
        </ReservationSchedule>
    </xsl:template>
</xsl:stylesheet>
...