2017-03-22 5 views
1

Ich kann normalerweise eine Antwort auf die Frage finden, die ich stelle, aber diese hat mich wirklich überkommen. Ich habe ein XSLT- und ein Input-XML-Dokument, wo ich eine Datetime von übergeordneten Elementen ziehen muss, die sich alle gegenseitig nachahmen. Wie ich dies formatiert habe, funktioniert es 80% der Zeit, aber die anderen 20% der Zeit es vermasselt und sendet die falsche Zeit aufgrund mehrerer derselben Status für die gleiche Einheit verwendet wird. ALL-Feld ist variabel, aber der Gerätestatus ist festgelegt. (Siehe XSLT).XSLT Auswählen bestimmter untergeordneter Elemente aus mehreren wiederkehrenden doppelten Headern

Problem: Die spätere Zeit überschreibt den früheren Zeitpunkt, wenn die Datei übermittelt wird.

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

EDIT Eingabedatei:

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

Stromausgang: (Es sendet angekommenen Knoten für zweimal Einheit E607, in welchem ​​Fall sie in der überschreibt DB und und nimmt die letzte Zeit, weil es die neueste aktualisierte Datei ist.)

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

gewünschte Ausgabe: (Ich muß es nur den früheren oder späteren Zeitpunkt für mehrere Status für das gleiche Gerät greifen)

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

Ich glaube nicht, dass wir das beantworten können, ohne Ihre Eingabe zu sehen. Im Allgemeinen sieht das wie ein Gruppierungsproblem aus, also fangen Sie hier an: http://www.jenitennison.com/xslt/grouping/muenchian.html –

+0

Eingabedatei hinzugefügt, (Whoops) – Willfergy

Antwort

0

das Beispiel zu minimieren, lassen Wir konzentrieren uns darauf, nur Ihre dritte ApparatusEvents Niederlassung zu produzieren. Wie ich bereits in den Kommentaren erwähnt habe, handelt es sich um ein klassisches Gruppierungsproblem nach Münch, mit zwei Komplikationen.

Die erste Komplikation ist, dass Sie nur einigeUN_HI Elemente berücksichtigen wollen - so müssen Sie einen Schlüssel definieren, die nur diese Knoten übereinstimmt (und Sie werden andere Tasten für die anderen ApparatusEvents Zweige definieren müssen), und wiederholen Sie das gleiche Prädikat beim Aufruf dieses Schlüssel:

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> 

die zweite Komplikation, die durch CDTS_DATETIME Sortieranlage ist eine chronologische nicht produzieren, Reihenfolge, weil das Format nicht YYYY-MM-DD ist. Das hat nichts mit dem Hauptproblem zu tun, deshalb werde ich nicht darauf eingehen. Sie können hier ein Beispiel sehen, wie Sie das hier angehen: Tokenize and compare dates in xslt 1.0

+0

Danke, ich muss schauen Muenchische Gruppierung und einige andere Funktionen in XSLT wie Key (die ich noch nie benutzt habe). – Willfergy

Verwandte Themen