2016-07-21 20 views
0

Ich bin mit einer Datentransformation Issuse und würde wirklich Ihre Hilfe und Beratung zu schätzen wissen.Conditional XML zu XML-Transformation

Ich möchte eine ziemlich große XML-Datei in ein anderes XML-Format umwandeln. Meine Kollegen sagen mir, dass die Verwendung von XSLT mein Problem lösen würde, aber auf den ersten Blick finde ich, dass XSLT nicht in der Lage ist, die bedingte Formatierung durchzuführen, die ich brauche. Wie Sie in meinem XML unter sehen können, muss ich eine Anzahl von Zeitreihen-Punkten von einem bestimmten Zeitintervall ableiten, das in den Start- und Endzeit-Tags beschrieben wird.

Meine Frage ist also, was ist die beste Praxis für ein solches Problem? Ist das mit XSLT oder einer anderen Technologie einfach lösbar? Oder wird am besten mit benutzerdefiniertem Code umgegangen?

Wir freuen uns auf Ihre Antworten.

Mit freundlichen Grüßen!

XML transformiert werden:

<starttime> 
    <datetime>201605130500</datetime> 
    <qualifier>163</Qualifier> 
</starttime> 
<endtime> 
    <datetime>201605150500</datetime> 
    <qualifier>164</Qualifier> 
</endtime> 
<seriesPeriod> 
    <quantityDetails> 
     <quantity>8.0</quantity> 
     <qualifier>135</qualifier> 
    </quantityDetails> 
    <datetimeDetails> 
     <datetime>201605130500201605130600</datetime> <!-- This is a period to from 05:00 to 06:00 (from-to YYYYMMDDHHH-YYYYMMDDHHH) --> 
     <qualifier>324</qualifier> 
    </datetimeDetails> 
</seriesPeriod> 
<seriesPeriod> 
    <quantityDetails> 
     <quantity>-11</quantity> 
     <qualifier>135</qualifier> 
    </quantityDetails> 
    <datetimeDetails> 
     <dateTime>201605130600201605130700</dateTime> 
     <qualifier>324</qualifier> 
    </datetimeDetails> 
</seriesPeriod> 
<!-- Continues with a total of 48 similar "seriesPeriod", one point for each hour in the timeinterval derived from starttime and endtime --> 

Erwartetes Ergebnis nach der Transformation:

<timeseries> 
    <timeinterval> 
     <start>2016-05-13T05:00Z</start> 
     <end>2016-05-15T05:00Z</end> 
    </timeinterval> 
    <point> 
     <position>1</position> 
     <quantity>8</quantity> 
    </point> 
    <point> 
     <position>2</position> 
     <quantity>-11</quantity> 
    </point> 
    <!-- Continues with a total of 48 similar "points", one point for each hour in the timeinterval --> 
</timeseries> 
+0

XSLT könnte hier ein gutes Werkzeug für die Aufgabe sein, aber Sie müssen die Logik Ihrer erforderlichen Transformation erklären. Insbesondere, woher kommen die "Quantity" -Werte in Ihrem erwarteten Ergebnis? Danke –

+0

Eine Erklärung der Logik - zusammen mit einem umfassenderen (und wohlgeformten!) Beispiel - wäre nützlich. Geben Sie auch an, ob Sie XSLT 2.0 verwenden können. –

+0

Bitte klären Sie, wie die Menge von "4" auf dem ersten Punkt und "-11" auf dem zweiten Punkt berechnet wird. –

Antwort

0

Ihre Frage ist nicht ganz klar. Vor allem der Teil über "bedingte Formatierung" - Ich sehe keine Bedingungen in Ihrer Beschreibung.

FWIW, das folgende Sheet:

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:template match="/root"> 
    <timeseries> 
     <timeinterval> 
      <start> 
       <xsl:call-template name="format-as-date"> 
        <xsl:with-param name="string" select="starttime/datetime"/> 
       </xsl:call-template> 
      </start> 
      <end> 
       <xsl:call-template name="format-as-date"> 
        <xsl:with-param name="string" select="endtime/datetime"/> 
       </xsl:call-template> 
      </end> 
     </timeinterval> 
     <xsl:for-each select="seriesPeriod"> 
      <point> 
       <position> 
        <xsl:value-of select="position()"/> 
       </position> 
       <quantity> 
        <xsl:value-of select="number(quantityDetails/quantity)"/> 
       </quantity> 
      </point> 
     </xsl:for-each> 
    </timeseries> 
</xsl:template> 

<xsl:template name="format-as-date"> 
    <xsl:param name="string"/> 
    <xsl:value-of select="substring($string, 1, 4)"/> 
    <xsl:text>-</xsl:text> 
    <xsl:value-of select="substring($string, 5, 2)"/> 
    <xsl:text>-</xsl:text> 
    <xsl:value-of select="substring($string, 7, 2)"/> 
    <xsl:text>T</xsl:text> 
    <xsl:value-of select="substring($string, 9, 2)"/> 
    <xsl:text>:</xsl:text> 
    <xsl:value-of select="substring($string, 11, 2)"/> 
    <xsl:text>Z</xsl:text> 
</xsl:template> 

</xsl:stylesheet> 

, wenn auf den folgenden wohlgeformten Eingang (!):

XML

<root> 
    <starttime> 
    <datetime>201605130500</datetime> 
    <qualifier>163</qualifier> 
    </starttime> 
    <endtime> 
    <datetime>201605150500</datetime> 
    <qualifier>164</qualifier> 
    </endtime> 
    <seriesPeriod> 
    <quantityDetails> 
     <quantity>8.0</quantity> 
     <qualifier>135</qualifier> 
    </quantityDetails> 
    <datetimeDetails> 
     <datetime>201605130500201605130600</datetime> 
     <qualifier>324</qualifier> 
    </datetimeDetails> 
    </seriesPeriod> 
    <seriesPeriod> 
    <quantityDetails> 
     <quantity>-11</quantity> 
     <qualifier>135</qualifier> 
    </quantityDetails> 
    <datetimeDetails> 
     <dateTime>201605130600201605130700</dateTime> 
     <qualifier>324</qualifier> 
    </datetimeDetails> 
    </seriesPeriod> 
</root> 

kehren:

Ergebnis

<?xml version="1.0" encoding="UTF-8"?> 
<timeseries> 
    <timeinterval> 
     <start>2016-05-13T05:00Z</start> 
     <end>2016-05-15T05:00Z</end> 
    </timeinterval> 
    <point> 
     <position>1</position> 
     <quantity>8</quantity> 
    </point> 
    <point> 
     <position>2</position> 
     <quantity>-11</quantity> 
    </point> 
</timeseries> 

die auf Ihr erwartetes Ergebnis identisch ist - entweder durch Design oder durch Zufall.

+0

Vielen Dank Michael! Ich bin sehr neu in XSLT, das hilft mir sehr beim Lernen. Was ich mit bedingter Formatierung meinte, war, dass ich dachte, ich müsste die Positionsnummerierung von der Start- und Endzeit herleiten, da mir "value-of select =" position() nicht bekannt war. – jstensen

+0

"* Ich dachte, ich müsste die Positionsnummerierung von der Start- und Endzeit ableiten *" Das wäre ein "interessantes" Problem gewesen ... –