.net XSLT 转换日期时间到日期格式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/487779/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 11:06:29  来源:igfitidea点击:

XSLT transformation datetime to date format

.netxsltxsd

提问by freggel

I'm trying to transform a datetime to a date format yyyy-MM-dd, because I'm using the xsd.exe tool the xs:date datatypes are automatically changed into a datetime datatype, because there is no type in the .NET Framework that matches the type xs:date completely.

我正在尝试将日期时间转换为日期格式 yyyy-MM-dd,因为我使用的是 xsd.exe 工具,xs:date 数据类型会自动更改为日期时间数据类型,因为 .NET 中没有类型完全匹配类型 xs:date 的框架。

But I can't get it to work

但我无法让它工作

<articles>
        <article>
          <articleid>48992</articleid>
          <deliverydateasked>2009-01-29T00:00:00+01:00</deliverydateasked>
        </article>
        <article>
          <articleid>48993</articleid>
          <deliverydateasked>2009-01-30T00:00:00+01:00</deliverydateasked>
        </article>
</articles>

trying to convert the xml to

试图将 xml 转换为

<articles>
        <article>
          <articleid>48992</articleid>
          <deliverydateasked>2009-01-29</deliverydateasked>
        </article>
        <article>
          <articleid>48993</articleid>
          <deliverydateasked>2009-01-30</deliverydateasked>
        </article>
</articles>

currently I'm using this XSLT

目前我正在使用这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
    <articles>
        <xsl:apply-templates select="article">
        </xsl:apply-templates>
            </articles>
</xsl:template>

<xsl:template name="FormatDate">

    <xsl:param name="DateTime" />
    <xsl:variable name="date">
        <xsl:value-of select="substring-before($DateTime,'T')" />
    </xsl:variable>

    <xsl:if test="string-length($date) != 10">
        <xsl:value-of select="$DateTime"/>
    </xsl:if>
    <xsl:if test="string-length($date) = 10">
        <xsl:value-of select="$date"/>
    </xsl:if>
</xsl:template>

<xsl:template match="article">
        <xsl:call-template name="FormatDate">
            <xsl:with-param name="DateTime" select="deliverydateasked"/>
        </xsl:call-template>    
</xsl:template>     

Does anyone know a good xslt transformation.

有谁知道一个好的 xslt 转换。

Thanks in advance

提前致谢

The output result of my code is

我的代码的输出结果是

<articles /> 

采纳答案by freggel

Thanks to Stesoc and annakata I figured it out This is the code I'm now using and it works perfect

感谢 Stesoc 和 annakata 我想通了这是我现在使用的代码,它工作得很好

<xsl:template match="*">
    <xsl:param name="parentElm">
        <xsl:value-of select="name(..)" />
    </xsl:param>
    <xsl:choose>
        <xsl:when test="local-name() = 'deliverydateasked'">
            <xsl:element name="deliverydateasked">
                <xsl:call-template name="FormatDate">
                    <xsl:with-param name="DateTime" select="."/>
                </xsl:call-template>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{local-name()}">
                <xsl:copy-of select="@*" />
                <xsl:apply-templates select="@* | node()" />
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="FormatDate">
    <xsl:param name="DateTime" />
    <xsl:variable name="date">
        <xsl:value-of select="substring-before($DateTime,'T')" />
    </xsl:variable>

    <xsl:if test="string-length($date) != 10">
        <xsl:value-of select="$DateTime"/>
    </xsl:if>
    <xsl:if test="string-length($date) = 10">
        <xsl:value-of select="$date"/>
    </xsl:if>
</xsl:template>     

回答by annakata

Frankly, this looks about right to me - sometimes a simple substring is good enough.

坦率地说,这对我来说似乎是正确的 - 有时一个简单的子字符串就足够了。

However, if you're in .NET land and you're really needing extra functionality .NET has XSLT Extension Objects

但是,如果您在 .NET 领域并且确实需要额外的功能,那么 .NET 具有XSLT 扩展对象



edit: oic, you've got a basic apply-templates conceptual problem. Try this (note the copy and the root template match):

编辑:oic,你有一个基本的应用模板概念问题。试试这个(注意副本和根模板匹配):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="*">
    <xsl:copy><xsl:apply-templates /></xsl:copy>
</xsl:template>

<xsl:template match="deliverydateasked">
    <xsl:copy>
        <xsl:call-template name="FormatDate">
            <xsl:with-param name="DateTime" select="."/>
        </xsl:call-template>    
    </xsl:copy>
</xsl:template>

<xsl:template name="FormatDate">

        <xsl:param name="DateTime" />
        <xsl:variable name="date">
                <xsl:value-of select="substring-before($DateTime,'T')" />
        </xsl:variable>

        <xsl:if test="string-length($date) != 10">
                <xsl:value-of select="$DateTime"/>
        </xsl:if>
        <xsl:if test="string-length($date) = 10">
                <xsl:value-of select="$date"/>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>

templates is a hard concept to learn, you might be better off starting with the more straightforward for-each, and/or it seems you could do with some XSLT tutorials/books.

模板是一个很难学习的概念,您最好从更直接的 开始for-each,和/或似乎您可以使用一些 XSLT 教程/书籍。

回答by Scott White

Formatting will get a lot easier in XPath 2.0, which Microsoft has currently refused to support for the last 8 years. Since the formatting issue is really only persistent for XSLT in .Net I like to use a custom function, which is cleaner & easier:

在 XPath 2.0 中格式化将变得更加容易,微软目前在过去 8 年中一直拒绝支持它。由于格式化问题实际上只对 .Net 中的 XSLT 持续存在,我喜欢使用自定义函数,它更清晰、更容易:

XSLT With Formatting Function:

带格式化功能的 XSLT:

    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:user="http://www.tempuri.org/User">

  <msxsl:script implements-prefix="user" language="C#">
        <![CDATA[
          public string FormatCurrency(string amount)
          {
            return decimal.Parse(amount).ToString("C0");
          }

          public string FormatDate(string dateValue)
          {
            return DateTime.Parse(dateValue).ToString("MM/dd/yyyy hh:mm");
          }
          ]]>
      </msxsl:script>

Usage:

用法:

<xsl:value-of select="user:FormatDate(@transactionDate)"/>
<xsl:value-of select="user:FormatCurrency(@amount)"/>

When you execute your XSLT in .Net make sure to tell it that it's trusted (so that the msxsl:script block will run.

当您在 .Net 中执行您的 XSLT 时,请确保告诉它它是受信任的(以便 msxsl:script 块将运行。

XslCompiledTransform.Load(reader, XsltSettings.TrustedXslt, null);