使用日期和时间逻辑模板从 xml 创建 JSON

Creating a JSON from xml with date and time logic templates

我正在尝试从包含消息的 XML 创建一个 JSON,每条消息都有其 date/time。

下面是XML

  <message>
     <messageText heading="Temporary Maintenance Message 1">test message1</messageText>

     <displayScheduleContainer>
        <startDate>22/05/2019</startDate>
        <startTimeHrs>12</startTimeHrs>
        <startTimeMins>45</startTimeMins>
        <noEndDate>true</noEndDate>
     </displayScheduleContainer>
  </message>

   <message>
     <messageText heading="Temporary Maintenance Message 1">test message2</messageText>

     <displayScheduleContainer>
        <startDate>22/06/2019</startDate>
        <startTimeHrs>12</startTimeHrs>
        <startTimeMins>45</startTimeMins>
        <noEndDate>true</noEndDate>
     </displayScheduleContainer>
  </message>

XSLT 中的逻辑读取日期和时间以激活消息

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

    <xsl:variable name="variableN">
        <xsl:call-template name="jsonMsg" />
    </xsl:variable>


    <xsl:choose>
        <xsl:when test="$variableN = 'true'">
            <xsl:copy-of select="messageText/text()" />
            <xsl:if test="position() &lt; last()">,</xsl:if>
        </xsl:when>

    </xsl:choose>

</xsl:for-each>

<xsl:template name="jsonMsg">
    <xsl:choose>
        <xsl:when 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:value-of select="$messageInDateTime" />
        </xsl:when>

    </xsl:choose>
</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>

我在这里面临的问题是,如果最后一个值是假的,我最终会在最后得到逗号。因为我正在检查最后一个位置并添加逗号。因此,整个 JSON 被破坏了。在这种情况下,它添加了逗号,因为我仅在它为真时才显示文本。

 "message": ["test message1", ]  

我正在使用 XSLT 1.0

而不是xsl:choose,将谓词附加到您的select表达式。这是一个简化的例子:

XML

<messages>
    <message>
        <messageText>test message1</messageText>
        <displayScheduleContainer>
            <noEndDate>true</noEndDate>
        </displayScheduleContainer>
    </message>
    <message>
        <messageText>test message2</messageText>
        <displayScheduleContainer>
            <noEndDate>true</noEndDate>
        </displayScheduleContainer>
    </message>
    <message>
        <messageText>test message3</messageText>
        <displayScheduleContainer>
            <noEndDate>false</noEndDate>
        </displayScheduleContainer>
    </message>
</messages>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/messages">
    <xsl:for-each select="message[displayScheduleContainer/noEndDate = 'true']">
        <xsl:value-of select="messageText" />
        <xsl:if test="position() &lt; last()">,</xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

结果

"test message1,test message2"

已添加:

如果测试太复杂而无法放入谓词,请分两次进行转换。这里再举一个简化的例子:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
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: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:stylesheet>

test 替换为:

<xsl:if test="displayScheduleContainer/noEndDate = 'true'">

与您要执行的test/s。