C# 通过 XSLT 在 XML 中格式化日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/500915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Format a date in XML via XSLT
提问by peterchen
When I use the XML serializer to serialize a DateTime
, it is written in the following format:
当我使用 XML 序列化程序序列化 a 时DateTime
,它以以下格式编写:
<Date>2007-11-14T12:01:00</Date>
When passing this through an XSLT stylesheet to output HTML, how can I format this? In most cases I just need the date, and when I need the time I of course don't want the "funny T" in there.
当通过 XSLT 样式表传递它以输出 HTML 时,我该如何格式化它?在大多数情况下,我只需要日期,而当我需要时间时,我当然不希望出现“有趣的 T”。
采纳答案by AnthonyWJones
Here are a couple of 1.0 templates that you can use:-
以下是您可以使用的几个 1.0 模板:-
<xsl:template name="formatDate">
<xsl:param name="dateTime" />
<xsl:variable name="date" select="substring-before($dateTime, 'T')" />
<xsl:variable name="year" select="substring-before($date, '-')" />
<xsl:variable name="month" select="substring-before(substring-after($date, '-'), '-')" />
<xsl:variable name="day" select="substring-after(substring-after($date, '-'), '-')" />
<xsl:value-of select="concat($day, ' ', $month, ' ', $year)" />
</xsl:template>
<xsl:template name="formatTime">
<xsl:param name="dateTime" />
<xsl:value-of select="substring-after($dateTime, 'T')" />
</xsl:template>
Call them with:-
打电话给他们:-
<xsl:call-template name="formatDate">
<xsl:with-param name="dateTime" select="xpath" />
</xsl:call-template>
and
和
<xsl:call-template name="formatTime">
<xsl:with-param name="dateTime" select="xpath" />
</xsl:call-template>
where xpath is the path to an element or attribute that has the standard date time format.
其中 xpath 是具有标准日期时间格式的元素或属性的路径。
回答by Dirk Vollmar
Date formatting is not easy in XSLT 1.0. Probably the most elegant way is to write a short XSLT extension function in C# for date formatting. Here's an example:
XSLT 1.0 中的日期格式并不容易。可能最优雅的方法是用 C# 编写一个简短的 XSLT 扩展函数来进行日期格式化。下面是一个例子:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:myExtension="urn:myExtension"
exclude-result-prefixes="msxsl myExtension">
<xsl:output method="xml" indent="yes"/>
<msxsl:script implements-prefix="myExtension" language="C#">
<![CDATA[
public string FormatDateTime(string xsdDateTime, string format)
{
DateTime date = DateTime.Parse(xsdDateTime);
return date.ToString(format);
}
]]>
</msxsl:script>
<xsl:template match="date">
<formattedDate>
<xsl:value-of select="myExtension:FormatDateTime(self::node(), 'd')"/>
</formattedDate>
</xsl:template>
</xsl:stylesheet>
With this input document
有了这个输入文件
<?xml version="1.0" encoding="utf-8"?>
<date>2007-11-14T12:01:00</date>
you will get
你会得到
<?xml version="1.0" encoding="utf-8"?>
<formattedDate>14.11.2007</formattedDate>
The function formatting the date takes a date value as string and a format as described in DateTime.ToString Method. Using .NET's DateTime struct gives you parsing arbitrary XSD datetime values (including time zone specifiers), timezone calculation and localized output for free.
格式化日期的函数采用字符串形式的日期值和DateTime.ToString 方法中所述的格式。使用 .NET 的 DateTime 结构,您可以免费解析任意 XSD 日期时间值(包括时区说明符)、时区计算和本地化输出。
However, be aware that there is one caveat (http://support.microsoft.com/kb/316775)with msxml script extensions: Each time you load the XSLT an assembly containing the script code is generated dynamically and loaded into memory. Due to the design of the .NET runtime, this assembly cannot be unloaded. That's why you have to make sure that your XSLT is only loaded once (and then cached for further re-use). This is especially important when running inside IIS.
但是,请注意msxml 脚本扩展有一个警告 (http://support.microsoft.com/kb/316775):每次加载 XSLT 时,都会动态生成一个包含脚本代码的程序集并将其加载到内存中。由于 .NET 运行时的设计,无法卸载此程序集。这就是为什么您必须确保您的 XSLT 只加载一次(然后缓存以供进一步重用)。这在 IIS 内运行时尤其重要。
回答by rivy
John Workman discusses this issue at length and gives several solutions in this discussion[1]on his blog. Basically, parse the individual date components and recombine in whatever order you wish. For your case, a pure XSLT 1.0+ version would be:
John Workman 详细讨论了这个问题,并在他的博客上的讨论[1] 中给出了几个解决方案。基本上,解析单个日期组件并按您希望的任何顺序重新组合。对于您的情况,纯 XSLT 1.0+ 版本将是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="date">
<!-- converts FROM <date>2001-12-31T12:00:00</date> TO some new format (DEFINED below) -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />
<xsl:variable name="year" select="substring($DateTime,1,4)" />
<xsl:variable name="month-temp" select="substring-after($DateTime,'-')" />
<xsl:variable name="month" select="substring-before($month-temp,'-')" />
<xsl:variable name="day-temp" select="substring-after($month-temp,'-')" />
<xsl:variable name="day" select="substring($day-temp,1,2)" />
<xsl:variable name="time" select="substring-after($DateTime,'T')" />
<xsl:variable name="hh" select="substring($time,1,2)" />
<xsl:variable name="mm" select="substring($time,4,2)" />
<xsl:variable name="ss" select="substring($time,7,2)" />
<!-- EUROPEAN FORMAT -->
<xsl:value-of select="$day"/>
<xsl:value-of select="'.'"/> <!--18.-->
<xsl:value-of select="$month"/>
<xsl:value-of select="'.'"/> <!--18.03.-->
<xsl:value-of select="$year"/>
<xsl:value-of select="' '"/> <!--18.03.1976 -->
<xsl:value-of select="$hh"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13: -->
<xsl:value-of select="$mm"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13:24 -->
<xsl:value-of select="$ss"/> <!--18.03.1976 13:24:55 -->
<!-- END: EUROPEAN FORMAT -->
</xsl:template>
Another format (REPLACEs the EUROPEAN FORMAT section):
另一种格式(替换 EUROPEAN FORMAT 部分):
<!-- Long DATE FORMAT -->
<xsl:choose>
<xsl:when test="$month = '1' or $month= '01'">January</xsl:when>
<xsl:when test="$month = '2' or $month= '02'">February</xsl:when>
<xsl:when test="$month= '3' or $month= '03'">March</xsl:when>
<xsl:when test="$month= '4' or $month= '04'">April</xsl:when>
<xsl:when test="$month= '5' or $month= '05'">May</xsl:when>
<xsl:when test="$month= '6' or $month= '06'">June</xsl:when>
<xsl:when test="$month= '7' or $month= '07'">July</xsl:when>
<xsl:when test="$month= '8' or $month= '08'">August</xsl:when>
<xsl:when test="$month= '9' or $month= '09'">September</xsl:when>
<xsl:when test="$month= '10'">October</xsl:when>
<xsl:when test="$month= '11'">November</xsl:when>
<xsl:when test="$month= '12'">December</xsl:when>
</xsl:choose>
<xsl:value-of select="' '"/> <!--January -->
<xsl:value-of select="$day"/> <!--January 12 -->
<xsl:value-of select="','"/> <!--January 12,-->
<xsl:value-of select="' '"/> <!--January 12, -->
<xsl:value-of select="$year"/> <!--January 12, 2001-->
<!-- END: Long DATE FORMAT -->
You can recombine the elements in any way you choose.
您可以按照您选择的任何方式重新组合元素。
[1] http://geekswithblogs.net/workdog/archive/2007/02/08/105858.aspx@@ http://archive.is/4Hjep
[1] http://geekswithblogs.net/workdog/archive/2007/02/08/105858.aspx@@ http://archive.is/4Hjep
回答by Andy
correction to roy's post: the day from the function will always get the month value. Use the following:
更正 roy 的帖子:函数中的日期将始终获得月份值。使用以下内容:
<xsl:variable name="year" select="substring($dateTime,1,4)" />
<xsl:variable name="month-temp" select="substring-after($dateTime,'-')" />
<xsl:variable name="month" select="substring-before($month-temp,'-')" />
<xsl:variable name="day-temp" select="substring-after($month-temp,'-')" />
<xsl:variable name="day" select="substring($day-temp,1,2)" />
<xsl:variable name="time" select="substring-after($dateTime,'T')" />
<xsl:variable name="hh" select="substring($time,1,2)" />
<xsl:variable name="mm" select="substring($time,4,2)" />
<xsl:variable name="ss" select="substring($time,7,2)" />
<xsl:value-of select="concat($month,'/',$day,'/',$year,' ',$hh,':',$mm,':',$ss)" />
回答by Jibran
Thanks, this post helped a lot.
谢谢,这篇文章很有帮助。
I was transforming an RSS feed which uses the following date format: Mon, 04 Apr 2011 23:18:00 -0700. Here is the named template I used to parse it.
我正在转换使用以下日期格式的 RSS 提要:Mon, 04 Apr 2011 23:18:00 -0700。这是我用来解析它的命名模板。
<!--Parse date format: Mon, 04 Apr 2011 23:18:00 -0700-->
<xsl:template name="formatDate">
<xsl:param name="dateIn" />
<xsl:variable name="day" select="substring($dateIn, 0, 3)" />
<xsl:variable name="date" select="substring($dateIn, 6, 2)" />
<xsl:variable name="month" select="substring($dateIn, 9, 3)" />
<xsl:variable name="year" select="substring($dateIn, 13, 4)" />
<xsl:variable name="hour" select="substring($dateIn, 18, 2)" />
<xsl:variable name="min" select="substring($dateIn, 21, 2)" />
<xsl:variable name="sec" select="substring($dateIn, 24, 2)" />
<xsl:value-of select="concat($date, ' ', $month, ' ', $year, ' ', $hour, ':', $min, ':', $sec)" />
</xsl:template>
回答by Phileas Fogg
Apologies for commenting on this old thread but for others finding it like me you could also use javascript if you are using an MS transformer:
抱歉评论这个旧线程,但对于其他像我一样发现它的人,如果您使用的是 MS 转换器,您也可以使用 javascript:
Declare the "msxsl" namespace:
声明“msxsl”命名空间:
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
Declare a namespace for your script:
为您的脚本声明一个命名空间:
xmlns:js="urn:custom-javascript"
(Optional) Omit the prefixes from the output:
(可选)省略输出中的前缀:
exclude-result-prefixes="msxsl js"
So you end up with an xsl declaration like this:
所以你最终会得到一个像这样的 xsl 声明:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:js="urn:custom-javascript"
exclude-result-prefixes="msxsl js">
Write the JavaScript in the msxsl:script element:
在 msxsl:script 元素中编写 JavaScript:
<msxsl:script language="JavaScript" implements-prefix="js">
<![CDATA[
function javascriptFunction(dateValue){
var date = new Date(dateValue);
if(!isNaN(date)) return date.toLocaleString();
return dateValue;
}
]]>
</msxsl:script>
Call your JavaScript function (using the XPath syntax '.' denoting 'this node'):
调用您的 JavaScript 函数(使用 XPath 语法“.”表示“此节点”):
<xsl:value-of select="js:javascriptFunction(string(.))"/>
NB: As of writing there doesn't seem to be an (xsl) way to include external js files (eg. jquery library). This could be done by parsing the xsl file server side before the transformation and adding the js file contents as a string into a CDATA section. I started to go down this route myself but concluded that if you need this level of functionality it might be better placed in a different part of the pipeline.
注意:在撰写本文时,似乎没有一种 (xsl) 方式来包含外部 js 文件(例如 jquery 库)。这可以通过在转换之前解析 xsl 文件服务器端并将 js 文件内容作为字符串添加到 CDATA 部分来完成。我自己开始沿着这条路线走下去,但得出的结论是,如果您需要这种级别的功能,最好将其放在管道的不同部分。
source: http://dev.ektron.com/kb_article.aspx?id=482
ref: http://www.ibm.com/developerworks/xml/library/x-tipxsltjs/index.html
来源:http: //dev.ektron.com/kb_article.aspx
? id= 482参考:http: //www.ibm.com/developerworks/xml/library/x-tipxsltjs/index.html
回答by Yogesh Sanchihar
<xsl:template match="date">
<xsl:copy>
<xsl:call-template name="formatdate">
<xsl:with-param name="DateTimeStr" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="formatdate">
<xsl:param name="DateTimeStr" />
<!-- input format xslt datetime string -->
<!-- output format mm/dd/yyyy -->
<xsl:variable name="datestr">
<xsl:value-of select="substring-before($DateTimeStr,'T')" />
</xsl:variable>
<xsl:variable name="mm">
<xsl:value-of select="substring($datestr,6,2)" />
</xsl:variable>
<xsl:variable name="dd">
<xsl:value-of select="substring($datestr,9,2)" />
</xsl:variable>
<xsl:variable name="yyyy">
<xsl:value-of select="substring($datestr,1,4)" />
</xsl:variable>
<xsl:value-of select="concat($mm,'/', $dd, '/', $yyyy)" />
</xsl:template>
This worked for me. You can check other options at :
这对我有用。您可以在以下位置检查其他选项:
https://blog.fpmurphy.com/2008/05/xslt-datetime-formatting.html
https://blog.fpmurphy.com/2008/05/xslt-datetime-formatting.html