使用日期和时间逻辑模板从xml创建JSON [英] Creating a JSON from xml with date and time logic templates

查看:97
本文介绍了使用日期和时间逻辑模板从xml创建JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从具有消息且每个消息都有其日期/时间的XML创建JSON.

I'm trying to create a JSON from a XML which has messages and each message has its 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内部的逻辑读取日期和时间以激活消息

The logic inside XSLT reads the date and time to activate the message

   <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>

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

The problem i'm facing here is if the last value is false, I end up getting the comma at the end. As i'm checking for the last position and adding the comma. Due to this the whole JSON is broken. In this case it adds the comma because i'm displaying the text only if it is true.

 "message": ["test message1", ]  

我正在使用XSLT 1.0

I'm using XSLT 1.0

推荐答案

代替xsl:choose,将谓词附加到select表达式中.这是一个简化的示例:

Instead of xsl:choose, append a predicate to your select expression. Here's a simplified example:

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"


已添加:

如果测试过于复杂而无法满足谓词的要求,则分两次进行转换.这里还是一个简化的示例:


Added:

If the test is too complex to fit in a predicate, do the transformation in two passes. Here, again, a simplified example:

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'">

包含要执行的测试.

这篇关于使用日期和时间逻辑模板从xml创建JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆