好的,所以我之前已经问过这个问题,但现在我正在努力实现这一目标,所以可以(希望)更好地解释。
我支持FileMaker应用程序,该应用程序已更新,允许用户以特定格式导出数据,总共有五个报告,并且每个报告在其生成的数据中都是正确的。为了使最终用户更容易理解输出,我们已经从使用字段名称的简单导出切换到使用XSL模板,以允许我们自定义结果的样子。除日期字段外,它都完美无缺。经过FileMaker论坛的讨论和后续帮助,我已经到了需要特定帮助的地步,我希望有人可以帮助我。
我将包含XSL的相关片段(因为样式表详细信息和标题行正常工作),但为了解释我的代码,我定义了几种样式:
<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, '0123456789.', ''), '')" />
</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或实际日期)都会被反转,月份不会以零为前缀,但空白日期似乎可以正确添加。
我确定这是导致这些问题的模板,但我无法看到我在哪里看错了!
感激不尽的任何帮助/建议
非常感谢
马丁
答案 0 :(得分: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>
注意:
这假设输入日期是DD / MM / YYYY或DD.MM.YYYY或DD-MM-YYYY格式(不是你问题中所述的YYYY / MM / DD),那一天和月值被零填充为两位数;
如果您使用的是Filemaker的内置XSLT引擎,则无法使用format-number()函数。如果您确实需要填充值,则必须使用其他设备,例如EXSLT str:align()扩展函数。
答案 1 :(得分: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) < 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>
感谢您的帮助/建议
马丁