2015-05-11 1 views
0

ОК, поэтому я спросил об этом раньше, но теперь я продвигаюсь вперед в том, чего я пытаюсь достичь, поэтому можно (надеюсь) объяснить лучше.
Я поддерживаю приложение FileMaker, которое было обновлено, чтобы пользователи могли экспортировать данные в определенных форматах, всего пять отчетов, и каждый из них является правильным в данных, которые он производит. Чтобы облегчить понимание конечным пользователем результата, мы переключились с простого экспорта с именами полей на использование шаблонов XSL, чтобы мы могли настроить, как выглядят результаты. Все работает отлично, за исключением полей даты. После обсуждений и последующей помощи на форумах FileMaker я дошел до того, что мне нужна конкретная помощь, и я надеюсь, что кто-то здесь может мне помочь.
я буду включать соответствующие фрагменты в XSL (как детали стилей и заголовки строк работают правильно), но объяснить свой код, я определяю несколько стилей:Проблема с шаблоном XSL для дат из Filemake Экспортированные данные

<Styles> 
    <Style ss:ID="Heading"> 
     <Font ss:Size="10" ss:Bold="1" /> 
    </Style> 
    <Style ss:ID="DateDisplay"> 
     <NumberFormat ss:Format="Short Date"/> 
    </Style> 
    <Style ss:ID="Other"/> 
    </Styles> 

И я написал шаблон для управления форматированием даты с нуля или преобразования из YYYY/MM/DD (формат, экспортируемый FileMaker) в YYYY-MM-DDTHH: MM: SS.000 (формат, подходящий для Excel для понимания).

<xsl:template name="format-date"> 
    <xsl:param name="dateParam" /> 
    <!--store default time to append to date--> 
    <xsl:variable name="timeFormat" select="concat('T', '00:00:00.000')"/> 
    <!--define default for blank dates--> 
    <xsl:choose> 
     <xsl:when test="$dateParam=''"> 
     <xsl:value-of select="concat('1900-01-01', timeFormat)" /> 
     </xsl:when> 
     <!--reformat non blank dates--> 
     <xsl:when test="$dateParam!=''"> 
     <!--store the month and day elements of the date--> 
     <xsl:choose> 
      <xsl:when test="contains($dateParam, '/')"> 
      <xsl:variable name="yearPart" select="substring-before($dateParam, '/')" /> 
      <xsl:variable name="monthPart" select="format-number(number(substring-before(substring-after($dateParam, '/'), '/')), '00')" /> 
      <xsl:variable name="dayPart" select="format-number(number(substring-after(substring-after($dateParam, '/'), '/')), '00')" /> 
      <!--concatenate all the parts to make a date in the correct format--> 
      <xsl:value-of select="concat($yearPart, '-', $monthPart, '-', $dayPart, $timeFormat)" /> 
      </xsl:when> 
      <xsl:when test="contains($dateParam, '.')"> 
      <xsl:variable name="yearPart" select="substring-before($dateParam, '.')" /> 
      <xsl:variable name="monthPart" select="format-number(number(substring-before(substring-after($dateParam, '.'), '.')), '00')" /> 
      <xsl:variable name="dayPart" select="format-number(number(substring-after(substring-after($dateParam, '.'), '.')), '00')" /> 
      <!--concatenate all the parts to make a date in the correct format--> 
      <xsl:value-of select="concat($yearPart, '-', $monthPart, '-', $dayPart, $timeFormat)" /> 
      </xsl:when> 
     </xsl:choose> 
     </xsl:when> 
    </xsl:choose> 
    </xsl:template> 

Проблема, которую я имею, что любая запись, которая содержит непустое или дату, которая не 1900/01/01 получает значение 1900-1-01T00: 00: 00.000, так что имеет неверное значение назначенный шаблоном XSL. Я запустил свой экспорт не используя XML (не XSL), чтобы подтвердить данные, и вот пример того, что получается:

<ROW MODID="4" RECORDID="19"> 
<COL><DATA>Company A Limited</DATA></COL> 
<COL><DATA>617642</DATA></COL> 
<COL><DATA>Company</DATA></COL> 
<COL><DATA>Walker, K</DATA></COL> 
<COL><DATA>Yes</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>Active</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA>01/01/1900</DATA></COL> 
<COL><DATA>Low risk</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>N</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>0</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>4715</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>1460</DATA></COL> 
</ROW> 
<ROW MODID="3" RECORDID="34"> 
<COL><DATA>Company B Limited</DATA></COL> 
<COL><DATA>662922</DATA></COL> 
<COL><DATA>Company</DATA></COL> 
<COL><DATA>Jones, A</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA>Active</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA>N</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>0</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>0</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>7973.75</DATA></COL> 
</ROW> 
<ROW MODID="3" RECORDID="89"> 
<COL><DATA>Company C Limited</DATA></COL> 
<COL><DATA>602611</DATA></COL> 
<COL><DATA>Trustee</DATA></COL> 
<COL><DATA>Smith, R</DATA></COL> 
<COL><DATA>Yes</DATA></COL> 
<COL><DATA>FTSE 100</DATA></COL> 
<COL><DATA>Active</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA>23/06/2004</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA /></COL> 
<COL><DATA>N</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>1816.25</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>0</DATA></COL> 
<COL><DATA /></COL> 
<COL><DATA>0</DATA></COL> 
</ROW> 

Мои результаты должны быть книги Excel с одним листом, ряд из них содержит смелые заголовки и строки 2 года являются данные, с датами в правильном формате, а также любые другие символы удаляются - вот заключительная часть кода:

<!--called for every "COL" node in a "ROW"--> 
    <xsl:template match="fmp:COL"> 
    <!--get the current field position--> 
    <xsl:variable name="i" select="position()" /> 
    <!--store the current field type--> 
    <xsl:variable name="fmType" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$i]/@TYPE" /> 
    <!--create and set field type variable--> 
    <xsl:variable name="ssType"> 
     <xsl:choose> 
     <xsl:when test="$fmType='NUMBER'">Number</xsl:when> 
     <xsl:when test="$fmType='DATE'">DateTime</xsl:when> 
     <xsl:otherwise>String</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <!--create and set cell style variable--> 
    <xsl:variable name="ssStyle"> 
     <xsl:choose> 
     <xsl:when test="$fmType='DATE'">DateDisplay</xsl:when> 
     <xsl:otherwise>Other</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <!--define cell and associated number format--> 
    <Cell ss:StyleID="{$ssStyle}"> 
     <!--define data and associated type--> 
     <Data ss:Type="{$ssType}"> 
     <xsl:variable name="d" select="fmp:DATA" /> 
     <xsl:choose> 
      <!--clean up number fields--> 
      <xsl:when test="$fmType='NUMBER'"> 
      <xsl:value-of select="translate($d, translate($d, '.', ''), '')" /> 
      </xsl:when> 
      <!--reformat date fields--> 
      <xsl:when test="$fmType='DATE'"> 
      <xsl:call-template name="format-date"> 
       <xsl:with-param name="dateParam" select="$d" /> 
      </xsl:call-template> 
      </xsl:when> 
      <!--pass other types unchanged--> 
      <xsl:otherwise> 
      <xsl:value-of select="$d" /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </Data> 
    </Cell>  
    </xsl:template> 

то, что я на самом деле получить за те же три записи (после запуска через XSL) это:

<Row> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Company A Limited</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">617642</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Company</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Walker, K</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Yes</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Active</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="DateDisplay"><Data ss:Type="DateTime">01-1-1900T00:00:00.000</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Low risk</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">N</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">0</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">4715</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">1460</Data></Cell> 
</Row> 
<Row> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Company B Limited</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">662922</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Company</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Jones, A</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Active</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="DateDisplay"><Data ss:Type="DateTime">1900-01-01</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">N</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">0</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">0</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">7973.75</Data></Cell> 
</Row> 
<Row> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Company C Limited</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">602611</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Trustee</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Smith, R</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Yes</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">FTSE 100</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">Active</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="DateDisplay"><Data ss:Type="DateTime">23-6-2004T00:00:00.000</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="String">N</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">1816.25</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">0</Data></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number"/></Cell> 
<Cell ss:StyleID="Other"><Data ss:Type="Number">0</Data></Cell> 
</Row> 

Таким образом, любые существующие даты (01/01/1900 или настоящая дата) меняются на противоположные, а месяц не имеет нуля, но пустая дата появляется правильно. Я уверен, что это мой шаблон, вызывающий эти проблемы, но я не вижу, где я поступил неправильно, глядя!
Любая помощь/советы с благодарностью получил
Большое спасибо
Martin

+0

Что такое правильный результат для записи с пустой датой? –

+0

Это 01/01/1900, и похоже, что он работает как ожидалось в коде: – MartinS

ответ

1

Как насчет простой:

<xsl:template name="format-date"> 
    <xsl:param name="dateParam"/> 
    <xsl:param name="time" select="'T00:00:00.000'"/> 
    <xsl:choose> 
     <xsl:when test="not(string($dateParam))">place your default result for blank dates here</xsl:when> 
     <xsl:otherwise> 
      <!-- normalize separators to "/" --> 
      <xsl:variable name="date" select="translate($dateParam, '.-', '//')"/> 
      <!-- extract date elements -->   
      <xsl:variable name="d" select="substring-before($date, '/')"/> 
      <xsl:variable name="m" select="substring-before(substring-after($date, '/'), '/')"/> 
      <xsl:variable name="y" select="substring-after(substring-after($date, '/'), '/')"/> 
      <!-- construct date from elements -->   
      <xsl:value-of select="concat($y, '-', $m, '-', $d, 'T00:00:00.000')" /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

Примечание:

  1. Это предполагает, что даты входные в формате DD/MM/YYYY или DD.MM.YYYY или DD-MM-YYYY (не ГГГГ/ММ/ДД, как указано в вашем вопросе), d, что значения «День» и «Месяц» равны нулю с двумя цифрами;

  2. Если вы используете встроенный XSLT-движок Filemaker, вы не можете использовать функцию format-number(). Если вам нужно вставить значения, вы должны использовать другое устройство, например. функция расширения EXSLT: align().

+0

Спасибо @ michael.hor257k! Я искал свои мозги, пытаясь понять, где я ошибся - я думаю, что читал дату в неправильном порядке, но замена других разделителей на/была определенно отличной идеей. Еще раз спасибо – MartinS

+0

Быстрый вопрос. Я все еще сталкиваюсь с другими столбцами даты, они возвращаются как «-T00: 00: 00.000», поэтому нет элемента даты. Я проверил в FileMaker - все даты отображаются в формате «dd mmm yyyy», но когда вы нажимаете в поле (в режиме макета), оно возвращается к «dd/mm/yyyy». поэтому даты выглядят так, как ожидалось, но я получаю эту проблему, которую я не видел в столбце более ранней даты. У первой строки с проблемой, по-видимому, имеются достоверные данные. Есть идеи? – MartinS

+0

На самом деле это происходит со всеми непустыми элементами. Я поменял окно редактирования для раскрывающегося календаря, но даты отображаются в макете просмотра всех записей. – MartinS

0

я получил там, и написали общий шаблон для борьбы с обоими (хотя хотелось бы понять, как управлять форматом вывода из Filemaker, но это другой вопрос!). Так вот мой рабочий код:

<!--set default and reformat dates--> 
    <xsl:template name="format-date"> 
    <xsl:param name="dateParam"/> 
    <!--store default time to append to date--> 
    <xsl:param name="time" select="'T00:00:00.000'"/> 
    <xsl:choose> 
     <!--set default value for blank entries--> 
     <xsl:when test="not(string($dateParam))"> 
     <xsl:value-of select="concat('1900-01-01', $time)" /> 
     </xsl:when> 
     <!--reformat non blank dates--> 
     <xsl:otherwise> 
     <xsl:choose> 
      <!--deal with dates in the format 'dd mmm yyyy'--> 
      <xsl:when test="contains($dateParam, ' ')"> 
      <xsl:variable name="d" select="substring-before($dateParam, ' ')"/> 
      <xsl:variable name="m" select="substring-before(substring-after($dateParam, ' '), ' ')"/> 
      <xsl:variable name="y" select="substring-after(substring-after($dateParam, ' '), ' ')"/> 
      <!--convert the month name to a number--> 
      <xsl:variable name="mNum" select=" 
          string-length(substring-before(
          'JanFebMarAprMayJunJulAugSepOctNovDec', 
          substring($m, 1, 3))) div 3 + 1" 
       /> 
      <xsl:choose> 
       <xsl:when test="number($mNum) &lt; 10"> 
       <!-- construct date from elements --> 
       <xsl:value-of select="concat($y, '-0', $mNum, '-', $d, $time)" /> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:value-of select="concat($y, '-', $mNum, '-', $d, $time)" /> 
       </xsl:otherwise> 
      </xsl:choose> 
      </xsl:when> 
      <xsl:otherwise> 
      <!-- normalize separators to "/" --> 
      <xsl:variable name="date" select="translate($dateParam, '.-', '//')"/> 
      <!-- extract date elements --> 
      <xsl:variable name="d" select="substring-before($date, '/')"/> 
      <xsl:variable name="m" select="substring-before(substring-after($date, '/'), '/')"/> 
      <xsl:variable name="y" select="substring-after(substring-after($date, '/'), '/')"/> 
      <!-- construct date from elements --> 
      <xsl:value-of select="concat($y, '-', $m, '-', $d, $time)" /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

Спасибо вам за помощь/совет
Martin

Смежные вопросы