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

Xslt 使用日期和时间逻辑模板从xml创建JSON,xslt,xpath,xslt-1.0,xpath-1.0,Xslt,Xpath,Xslt 1.0,Xpath 1.0,我试图从一个包含消息的XML创建一个JSON,每个消息都有它的日期/时间 下面是XML <message> <messageText heading="Temporary Maintenance Message 1">test message1</messageText> <displayScheduleContainer> <startDate>22/05/2019</startDate

我试图从一个包含消息的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>

我使用的是XSLT1.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>

补充: 如果测试太复杂,无法放入谓词,则分两次进行转换。这里再次提供一个简化示例:

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

使用要执行的测试。

仅选择满足条件的消息。无法向您演示如何操作,因为您没有发布。显示的代码片段没有任何意义,因为所有消息的变量值都是相同的。@michael.hor257k我在原始问题中添加了更详细的版本。请让我知道这是否有助于解释问题。您应该发布无需修改即可运行的代码(XML+XSLT)。这里的问题是,在计算确定消息是否必须显示的计时逻辑后,模板返回的true或false值。即使调用了
另一个模板,并决定是否必须显示消息,我恐怕无法在没有对需要应用的逻辑进行解释的情况下进行进一步评论。通常,如果不能使用谓词,则可以使用变量仅存储符合条件的消息,然后对该消息运行
xsl:for each
。似乎您已经有了这样的变量,所以您可以在填充它时进行此消除(问题中未显示此步骤)。逻辑在
noEndDateTemplate
中,我在初始问题中也粘贴了此逻辑。该模板将给定的XML日期和时间与服务器进行比较,并返回true或false。我已经在存储变量
“$variableN='true'”
中返回的值,但是如果最后一个值为false,则前一个值不知道它。是否可以在单个数组中捕获所有带有“true”的值,然后对其上的每个
处理一个
xsl:for?是的,请参阅我答案的补充。
<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>
<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"
<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>
<xsl:if test="displayScheduleContainer/noEndDate = 'true'">