我正在尝试从具有消息的XML创建一个JSON,每个消息都有其日期/时间。
下面是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() < 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) < 0">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>false</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
我在这里遇到的问题是,如果最后一个值是错误的,那么我最终会在最后获得逗号。当我要检查最后一个位置并添加逗号时。因此,整个JSON被打破了。在这种情况下,它会添加逗号,因为我仅在文本为true时才显示逗号。
"message": ["test message1", ]
我正在使用XSLT 1.0
而不是 xsl:choose
,将a 谓词附加到您的 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() < 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() < last()">,</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
替换:
替换test
<xsl:if test="displayScheduleContainer/noEndDate = 'true'">
在您要执行的测试中。