2016-07-21 1 views
0

Я борюсь с преобразованием данных и очень ценю вашу помощь и советы.Преобразование преобразований XML в XML

Я хотел бы преобразовать довольно большой XML-файл в другой формат XML. Мои коллеги говорят мне, что использование XSLT решит мою проблему, однако на первый взгляд я считаю, что XSLT не способен выполнять условное форматирование, которое мне нужно. Как вы можете видеть из моего xml, мне нужно получить несколько таймсерийных точек из указанного интервала времени, описанного в тегах начала и окончания.

Мой вопрос, поэтому, что такое лучшая практика для такой проблемы? Легко ли это разрешимо с помощью XSLT или с использованием другой технологии? Или это лучший способ написания пользовательского кода?

Ждем ваших ответов.

С уважением!

XML трансформироваться:

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

Ожидаемый результат после преобразования:

<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 может быть хорошим инструментом для задачи здесь, но вам нужно будет объяснить логику вашей необходимой трансформации. В частности, где значения «количества» исходят из ожидаемого результата? Спасибо –

+0

Объяснение логики - наряду с более полным (и правильно сформированным!) Примером - было бы полезно. Также укажите, можете ли вы использовать XSLT 2.0. –

+0

Уточните, как рассчитывается количество «4» в первой точке и «-11» на второй точке. –

ответ

0

Ваш вопрос не совсем ясен. Особенно в разделе «условное форматирование» - Я не вижу никаких условий в вашем описании.

FWIW, следующая таблица стилей:

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> 

при нанесении на следующей хорошо сформированным вход (!):

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> 

вернется:

Результат

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

который идентичен вашему ожидаемому результату - либо конструкции, или случайно.

+0

Большое спасибо Майклу! Я очень новичок в XSLT, поэтому это помогает мне в обучении. То, что я подразумевал при условном форматировании, состояло в том, что я думал, что мне нужно будет вывести нумерацию позиций с начала и конца, поскольку я не знал о значении «value-of select =» position(). – jstensen

+0

"* Я думал, что мне придется вывести нумерацию позиций с начала и конца *« Это было бы «интересной» проблемой ... –