C# 使用xslt在Xml中重新格式化日期 2018年2月28日上午12:00:00 01/01/0001 12:00:00 AM 2018年1月29日12:00:00上午
这是我想要循环使用的一些xml文件,并使用xslt更改所有日期,以使用xml linq获得所有日期,如2018-04-15T00:00:00格式:C# 使用xslt在Xml中重新格式化日期 2018年2月28日上午12:00:00 01/01/0001 12:00:00 AM 2018年1月29日12:00:00上午,c#,xml,xslt,C#,Xml,Xslt,这是我想要循环使用的一些xml文件,并使用xslt更改所有日期,以使用xml linq获得所有日期,如2018-04-15T00:00:00格式: <BatchInput> <DealInfoObject> <DealThirdParty> <ThirdpartyPayment> <DueDate></DueD
<BatchInput>
<DealInfoObject>
<DealThirdParty>
<ThirdpartyPayment>
<DueDate></DueDate>
<DeliveryDate>28/02/2018 12:00:00 AM</DeliveryDate>
<AdvanceDate>01/01/0001 12:00:00 AM</AdvanceDate>
<ThirdPartySchedule>
<DueDate>29/01/2018 12:00:00 AM</DueDate>
</ThirdPartySchedule>
</ThirdpartyPayment>
<DealThirdParty>
<DealInfoObject>
<BatchInput>
该示例在输入格式方面不明确。假设小时数是零填充到2位数长度,您可以执行以下操作: XSLT1.0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var dates = doc.Descendants().Where(x => x.Name.LocalName.Contains("Date") && ((string)x != string.Empty));
foreach (var date in dates)
{
date.SetValue(((DateTime)date).ToUniversalTime());
}
}
}
}
如果确实有空的日期元素,则需要做更多的工作。由于没有指定XSLT版本,我使用了2.0版 我的想法是转换每个文本节点,其中包含一个日期 格式转换为“正确”格式。 如果文本节点有其他内容(与日期模式不匹配) 它保持不变 优点是如果您有其他带有日期的标签, 无需更改XSLT脚本
<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:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DeliveryDate | AdvanceDate | DueDate">
<xsl:copy>
<xsl:variable name="d" select="substring(., 1, 2)"/>
<xsl:variable name="m" select="substring(., 4, 2)"/>
<xsl:variable name="y" select="substring(., 7, 4)"/>
<xsl:variable name="h12" select="substring(., 12, 2)"/>
<xsl:variable name="mmss" select="substring(., 14, 6)"/>
<xsl:variable name="pm" select="contains(.,'P')"/>
<xsl:variable name="h24" select="$h12 mod 12 + 12*$pm"/>
<xsl:value-of select="$y"/>
<xsl:value-of select="format-number($m, '-00')"/>
<xsl:value-of select="format-number($d, '-00')"/>
<xsl:value-of select="format-number($h24, 'T00')"/>
<xsl:value-of select="$mmss"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
重新格式化问题中的XML,并向我们展示您目前正在使用的XSLT。一个简洁的问题将得到一个简洁的答案,并使之成为有效的XML——最后三个“开始元素”应该是“结束元素”。最好是XML文件的作者将其修复,并生成ISO8601日期。这个文件使用特定于语言环境的日期我有点惊讶于您接受了一个不起作用的答案,并且没有使用XSLT。您真的不需要它来处理示例XML中提供的格式的输入吗?您不在乎它是否使用XSLT吗?(如果是,为什么要求XSLT?)a)这不是按照要求使用XSLT;b) 转换到DateTime
将失败,因为LINQ to XML希望值的格式正确。为什么ToFileTimeUtc
?OP不是问文件时间。这是ISO8601格式。如果您不想要时区,可以使用ToString(“s”)
获取,如果您想要时区,可以使用o
获取。顺便说一句,这假设您首先解析文本以获得DateTime
值(基本上,使用问题中给出的XML尝试此代码,修复了关闭标记-它将失败。)修复。正如标签上所说,这仍然是一个c#解决方案。不,它不是固定的。这段代码仍然失败——而且不仅仅是标签的要求。如果您不同意这些要求,那么值得在注释中询问更多细节。我有时用来验证日期格式的一个技巧是谓词[翻译(,'123456789P','000000000A')='00/00/0000 00:00:00 AM']
(对于这个问题的给定日期格式),虽然您可能需要额外的模板来处理不符合该格式的元素。@flyn1179我使用。但OP需要澄清这是否需要(我怀疑不是)。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="text()[normalize-space()]">
<xsl:variable name="mtch"
select="matches(., '^\d\d/\d\d/\d{4} \d\d:\d\d:\d\d [A|P]M$')"/>
<xsl:if test="$mtch">
<xsl:variable name="dt" select="xs:date(concat(
substring(., 7, 4), '-', substring(., 4, 2), '-', substring(., 1, 2)))"/>
<xsl:variable name="am" as="xs:string" select="substring(., 21, 2)"/>
<xsl:variable name="hr" as="xs:string" select="substring(., 12, 2)"/>
<xsl:variable name="hri" as="xs:integer" select="
if ($am = 'AM') then xs:integer($hr) mod 12
else xs:integer($hr) mod 12 + 12"/>
<xsl:variable name="hrs" as="xs:string" select="format-number($hri, '00')"/>
<xsl:variable name="mm" as="xs:string" select="substring(., 15, 2)"/>
<xsl:variable name="ss" as="xs:string" select="substring(., 18, 2)"/>
<xsl:variable name="tm" select="xs:time(concat($hrs, ':', $mm, ':', $ss))"/>
<xsl:variable name="dtm" select="dateTime($dt, $tm)"/>
<xsl:value-of select="$dtm"/>
</xsl:if>
<xsl:if test="not($mtch)">
<xsl:value-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>