Вывод JSON с использованием логики синхронизации в XSLT 1.0 - PullRequest
0 голосов
/ 19 мая 2019

Я пытаюсь читать сообщения в формате XML и выводить их в формате JSON.Каждое сообщение также имеет временную логику для отображения и скрытия сообщения.

Ниже приведен мой XML, в котором каждое сообщение имеет дату и время начала и окончания

<activeMessage>
<message>
<messageText>test message 1</messageText>
<displayScheduleContainer>
<startDate>17/05/2019</startDate>
<startTimeHrs>12</startTimeHrs>
<startTimeMins>00</startTimeMins>
<noEndDate/>
<endDate>17/05/2019</endDate>
<endTimeHrs>23</endTimeHrs>
<endTimeMins>59</endTimeMins>
</displayScheduleContainer>
</message>  

Ниже мой XSL

<xsl:for-each select="xalan:nodeset($messageData)/activeMessage/message">

                    <xsl:variable name="messageInDateTime">
                        <xsl:call-template name="dateLessThanTemplate">
                            <xsl:with-param name="startDateTime" select="concat(displayScheduleContainer/startDate, ' ', displayScheduleContainer/startTimeHrs, ':', displayScheduleContainer/startTimeMins)" />
                            <xsl:with-param name="endDateTime" select="concat(displayScheduleContainer/endDate, ' ', displayScheduleContainer/endTimeHrs, ':', displayScheduleContainer/endTimeMins)" />
                        </xsl:call-template>
                    </xsl:variable>

                    <xsl:if test="$messageInDateTime = 'true'">
                        <xsl:choose>
                            <xsl:when test="position()=1">
                                <xsl:call-template name="singleMessageJSON" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:call-template name="multiMessageJSON" />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:if>
        </xsl:for-each>

1 Ответ

0 голосов
/ 20 мая 2019

Поскольку вы добавили тег для XSLT 3, я думаю, что вы можете избавиться от любого вызова Java и просто использовать, например,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:function name="mf:get-dateTime" as="xs:dateTime?">
      <xsl:param name="date" as="xs:string"/>
      <xsl:param name="hours" as="xs:string"/>
      <xsl:param name="minutes" as="xs:string"/>
      <xsl:try 
        select="xs:dateTime(replace($date, '([0-9]{2})/([0-9]{2})/([0-9]{4})', '$3-$2-$1') || 'T' || $hours || ':' || $minutes || ':00')">
          <xsl:catch select="()"/>
      </xsl:try>
  </xsl:function>

  <xsl:param name="now" select="current-dateTime()"/>
  <xsl:output method="json" indent="yes"/>

  <xsl:template match="activeMessage">
      <xsl:sequence
        select="map { 
          'message' : array { 
            message[mf:get-dateTime(displayScheduleContainer/startDate, displayScheduleContainer/startTimeHrs, displayScheduleContainer/startTimeMins) lt $now
                    and 
                    mf:get-dateTime(displayScheduleContainer/endDate, displayScheduleContainer/endTimeHrs, displayScheduleContainer/endTimeMins) gt $now]/messageText[normalize-space()]/string() 
            }
          }"/>
  </xsl:template>

</xsl:stylesheet>

в XSLT 3 с Saxon 9.8 или новее.Я не уверен в том, какой именно выходной формат JSON вам нужен, но главное преимущество XSLT 3 состоит в том, что вы можете создавать карты и массивы в XSLT / XPath, и при необходимости они сериализуются как JSON, не беспокоясь о том, чтобы выводить запятые в нужном месте..

https://xsltfiddle.liberty -development.net / bnnZWx / 1

Вероятно, было бы лучше перенести два сравнения дат в другую функцию, так как тогда предикатстановится более читабельным:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:function name="mf:get-dateTime" as="xs:dateTime?">
      <xsl:param name="date" as="xs:string"/>
      <xsl:param name="hours" as="xs:string"/>
      <xsl:param name="minutes" as="xs:string"/>
      <xsl:try 
        select="xs:dateTime(replace($date, '([0-9]{2})/([0-9]{2})/([0-9]{4})', '$3-$2-$1') || 'T' || $hours || ':' || $minutes || ':00')">
          <xsl:catch select="()"/>
      </xsl:try>
  </xsl:function>

  <xsl:function name="mf:compare-dates" as="xs:boolean">
      <xsl:param name="schedule" as="element(displayScheduleContainer)"/>
      <xsl:sequence
        select="mf:get-dateTime($schedule/startDate, $schedule/startTimeHrs, $schedule/startTimeMins) lt $now
                and 
                mf:get-dateTime($schedule/endDate, $schedule/endTimeHrs, $schedule/endTimeMins) gt $now"/>
  </xsl:function>

  <xsl:param name="now" select="current-dateTime()"/>
  <xsl:output method="json" indent="yes"/>

  <xsl:template match="activeMessage">
      <xsl:sequence
        select="map { 
          'message' : array { 
            message[mf:compare-dates(displayScheduleContainer)]/messageText[normalize-space()]/string() 
            }
          }"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bnnZWx / 2

...