Избавиться от запятой для последнего элемента в каждом цикле - PullRequest
0 голосов
/ 25 мая 2019

Я пытаюсь создать JSON из XML, в котором есть сообщения, и у каждого сообщения есть дата / время.

XML

  <messages>
    <message>
        <messageText>test message1</messageText>
        <displayScheduleContainer>
<startDate>22/05/2019</startDate>
<startTimeHrs>12</startTimeHrs>
<startTimeMins>45</startTimeMins>
            <noEndDate>true</noEndDate>
        </displayScheduleContainer>
    </message>
    <message>
        <messageText>test message2</messageText>
        <displayScheduleContainer>
<startDate>22/06/2019</startDate>
<startTimeHrs>12</startTimeHrs>
<startTimeMins>45</startTimeMins>
            <noEndDate>true</noEndDate>
        </displayScheduleContainer>
    </message>
    <message>
        <messageText>test message3</messageText>
        <displayScheduleContainer>
<startDate>22/06/2019</startDate>
<startTimeHrs>12</startTimeHrs>
<startTimeMins>45</startTimeMins>
            <noEndDate>false</noEndDate>
        </displayScheduleContainer>
    </message>
</messages>

Логика внутри XSLT читает дату ивремя активировать сообщение

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" xmlns:java="java"  xmlns:xalan="http://xml.apache.org/xalan"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/messages">
    <!-- first pass -->
    <xsl:variable name="eligible-messages">
        <xsl:for-each select="message">

            <xsl:if test="displayScheduleContainer/noEndDate = 'true'">
              <xsl:variable name="messageInDateTime">
        <xsl:call-template name="noEndDateTemplate">
           <xsl:with-param name="startDateTime" select="concat(displayScheduleContainer/startDate, ' ', displayScheduleContainer/startTimeHrs, ':', displayScheduleContainer/startTimeMins)" />
         </xsl:call-template>
        </xsl:variable>
      <xsl:if test="$messageInDateTime = 'true'" >
                    <xsl:copy-of select="messageText/text()" />
                    <xsl:if test="position() &lt; last()">,</xsl:if>

                 </xsl:if>
            </xsl:if>

        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
<xsl:value-of select="$eligible-messages" />
</xsl:template>

<xsl:template name="noEndDateTemplate">
        <xsl:param name="startDateTime" />
        <xsl:variable name="sdf" select="java:text.SimpleDateFormat.new('dd/MM/yyyy hh:mm')" />
        <xsl:variable name="currentDateTime" select="java:util.Date.new()" />
        <xsl:choose>
            <xsl:when test="java:compareTo(java:parse($sdf, $startDateTime), $currentDateTime) &lt; 0">
                <xsl:text>true</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>false</xsl:text>
            </xsl:otherwise>
        </xsl:choose>


    </xsl:template>

</xsl:stylesheet>

Проблема, с которой я здесь сталкиваюсь, заключается в том, что если последнее значение равно false, я получаю запятую в конце.Поскольку я проверяю последнюю позицию и добавляю запятую.Из-за этого весь JSON нарушается.В этом случае он добавляет запятую, потому что я отображаю текст, только если он истинен.

Вывод получен

test message1,

1 Ответ

1 голос
/ 25 мая 2019

Вы неправильно выполняете ответ, полученный на ваш p ​​ повторный вопрос . Боюсь, я не могу проверить ваш Java-код, но я верю, что получаю правильный результат, используя:

XSLT 1.0 (+ EXSLT + Java)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" xmlns:java="java"  
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/messages">
    <!-- first pass -->
    <xsl:variable name="eligible-messages">
        <xsl:for-each select="message[displayScheduleContainer/noEndDate = 'true']">
            <xsl:variable name="messageInDateTime">
                <xsl:call-template name="noEndDateTemplate">
                    <xsl:with-param name="startDateTime" select="concat(displayScheduleContainer/startDate, ' ', displayScheduleContainer/startTimeHrs, ':', displayScheduleContainer/startTimeMins)" />
                </xsl:call-template>
            </xsl:variable>
            <xsl:if test="$messageInDateTime = 'true'" >
                <xsl:copy-of select="." />
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <xsl:for-each select="exsl:node-set($eligible-messages)/message">
        <xsl:value-of select="messageText" />
        <xsl:if test="position() &lt; last()">,</xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:template name="noEndDateTemplate">
    <xsl:param name="startDateTime" />
    <xsl:variable name="sdf" select="java:text.SimpleDateFormat.new('dd/MM/yyyy hh:mm')" />
    <xsl:variable name="currentDateTime" select="java:util.Date.new()" />
    <xsl:value-of select="java:compareTo(java:parse($sdf, $startDateTime), $currentDateTime) &lt; 0"/>  
</xsl:template>

</xsl:stylesheet>
...