我通常可以找到我问的问题的答案,但这个问题真的让我很难过。我有一个XSLT和一个输入XML文档,我需要从父元素中提取日期时间,这些元素都是模仿彼此的。我如何格式化,它在80%的时间内工作,但另外20%的时间它会混乱并发送错误的时间,因为使用的是同一个单元的多个相同状态。 ALL字段是可变的,但设置了单位状态。 (参见XSLT)。
问题:稍后时间会覆盖文件提交的早期时间。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<soap:Envelope xsl:version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ApparatusEvents>
<xsl:for-each select="/ICADLINK_EVENT/UN_HI_LIST/UN_HI">
<xsl:if test="UNIT_STATUS = 'DP' and DGROUP = 'SNR'">
<ApparatusEvent>
<Apparatus>
<xsl:value-of select="UNID"/>
</Apparatus>
<Type>Dispatch</Type>
<DateTime>
<xsl:value-of select="CDTS_TIMESTAMP/CDTS_DATETIME"/>
</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</xsl:if>
</xsl:for-each>
</ApparatusEvents>
<ApparatusEvents>
<xsl:for-each select="/ICADLINK_EVENT/UN_HI_LIST/UN_HI">
<xsl:if test="UNIT_STATUS = 'ER' and DGROUP = 'SNR'">
<ApparatusEvent>
<Apparatus>
<xsl:value-of select="UNID"/>
</Apparatus>
<Type>Enroute</Type>
<DateTime>
<xsl:value-of select="CDTS_TIMESTAMP/CDTS_DATETIME"/>
</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</xsl:if>
</xsl:for-each>
</ApparatusEvents>
<ApparatusEvents>
<xsl:for-each select="/ICADLINK_EVENT/UN_HI_LIST/UN_HI">
<xsl:if test="UNIT_STATUS = 'AR' and DGROUP = 'SNR'">
<ApparatusEvent>
<Apparatus>
<xsl:value-of select="UNID"/>
</Apparatus>
<Type>Arrived</Type>
<DateTime>
<xsl:value-of select="CDTS_TIMESTAMP/CDTS_DATETIME"/>
</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</xsl:if>
</xsl:for-each>
</ApparatusEvents>
</soap:Body>
</soap:Envelope>
</xsl:template>
编辑输入文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ICADLINK_EVENT version="1.0" creationdate="3/29/2016 8:34:57 AM">
<UN_HI_LIST>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:12:54</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:12:54</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E7</UNID>
<UNIT_STATUS>DP</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:13:54</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:13:54</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E7</UNID>
<UNIT_STATUS>ER</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:15:05</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:15:05</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E607</UNID>
<UNIT_STATUS>DP</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:15:05</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:15:05</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E607</UNID>
<UNIT_STATUS>ER</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:20:39</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:20:39</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E607</UNID>
<UNIT_STATUS>AR</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:21:19</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:21:19</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E7</UNID>
<UNIT_STATUS>AR</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
<UN_HI>
<CDTS_TIMESTAMP>
<CDTS_DATE>3/29/2016</CDTS_DATE>
<CDTS_TIME>08:21:46</CDTS_TIME>
<CDTS_DATETIME>3/29/2016 08:21:46</CDTS_DATETIME>
</CDTS_TIMESTAMP>
<UNID>E607</UNID>
<UNIT_STATUS>AR</UNIT_STATUS>
<DGROUP>SNR</DGROUP>
</UN_HI>
当前输出:(它将E607单元的Arrived节点发送两次,在这种情况下,它会在数据库中覆盖并占用最新时间,因为它是最新更新的文件。)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ApparatusEvents>
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Dispatch</Type>
<DateTime>3/29/2016 08:12:54</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Dispatch</Type>
<DateTime>3/29/2016 08:15:05</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents>
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Enroute</Type>
<DateTime>3/29/2016 08:13:54</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Enroute</Type>
<DateTime>3/29/2016 08:15:05</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Arrived</Type>
<DateTime>**3/29/2016 08:20:39**</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Arrived</Type>
<DateTime>3/29/2016 08:21:19</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Arrived</Type>
<DateTime>**3/29/2016 08:21:46**</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
</soap:Body>
所需输出:(我需要它才能获取SAME单元的多个状态的早期或更晚时间)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ApparatusEvents>
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Dispatch</Type>
<DateTime>3/29/2016 08:12:54</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Dispatch</Type>
<DateTime>3/29/2016 08:15:05</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents>
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Enroute</Type>
<DateTime>3/29/2016 08:13:54</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Enroute</Type>
<DateTime>3/29/2016 08:15:05</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents>
**<ApparatusEvent>
<Apparatus>E607</Apparatus>
<Type>Arrived</Type>
<DateTime>3/29/2016 08:20:39</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>**
<ApparatusEvent>
<Apparatus>E7</Apparatus>
<Type>Arrived</Type>
<DateTime>3/29/2016 08:21:19</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</ApparatusEvents>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
<ApparatusEvents/>
</soap:Body>
答案 0 :(得分:0)
为了最大限度地减少这个例子,让我们专注于只生成你的第三个ApparatusEvents
分支。正如我在评论中提到的,这是一个典型的Muenchian分组问题,有两个复杂问题。
第一个复杂因素是你只想考虑一些 UN_HI
元素 - 所以你需要定义一个只匹配这些节点的键(你必须定义其他键)其他ApparatusEvents
分支),并在调用此密钥时重复相同的谓词:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="key3" match="UN_HI[UNIT_STATUS='AR' and DGROUP='SNR']" use="UNID" />
<xsl:template match="/">
<soap:Envelope xsl:version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<!-- skipped -->
<ApparatusEvents>
<xsl:variable name="records" select="/ICADLINK_EVENT/UN_HI_LIST/UN_HI[UNIT_STATUS='AR' and DGROUP='SNR']"/>
<!-- for each distinct group -->
<xsl:for-each select="$records[count(. | key('key3', UNID)[1]) = 1]">
<!-- get the earliest record in this group -->
<xsl:for-each select="key('key3', UNID)">
<xsl:sort select="CDTS_TIMESTAMP/CDTS_DATETIME" data-type="text" order="ascending"/>
<xsl:if test="position()=1">
<ApparatusEvent>
<Apparatus>
<xsl:value-of select="UNID"/>
</Apparatus>
<Type>Arrived</Type>
<DateTime>
<xsl:value-of select="CDTS_TIMESTAMP/CDTS_DATETIME"/>
</DateTime>
<UnitCancelledFlag>false</UnitCancelledFlag>
</ApparatusEvent>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</ApparatusEvents>
</soap:Body>
</soap:Envelope>
</xsl:template>
</xsl:stylesheet>
第二个复杂因素是按CDTS_DATETIME
排序不会产生按时间顺序排列,因为格式不是YYYY-MM-DD
。这与这里的主要问题无关,所以我不打算讨论它。您可以在此处查看如何处理此问题的示例:Tokenize and compare dates in xslt 1.0