#xslt #xslt-1.0
#xslt #xslt-1.0
Вопрос:
У меня есть 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:
Вы 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>
Комментарии:
1. Ах да, конечно. Я думаю, это должен быть какой-то простой Xpath. <xsl: для каждого select=»//резервирование[тип=’2′]»> СПАСИБО!!