在执行xslt转换时,时区以一种奇怪的方式序列化。
我尝试在xalan和jaxen之间切换实现,但是没有观察到任何变化。
试图手动地格式化日期,但似乎找不到使用它添加时区的方法(例如,+05:30或-08:00)。
有没有人遇到过类似的问题?
结果产生
<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns:date="http://exslt.org/dates-and-times" version="1.0">
2019-06-20T10:23:31+05:1800000
</Test>预期结果
<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns:date="http://exslt.org/dates-and-times" version="1.0">
2019-06-20T10:23:31+05:30
</Test>我的示例代码如下
Main.java
package test;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.TimeZone;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Main {
public static void main(String[] args) {
printTransformed(TimeZone.getTimeZone("Asia/Kolkata"));
}
private static void printTransformed(TimeZone timeZone) {
TimeZone.setDefault(timeZone);
try {
final StreamSource source = new StreamSource(
Files.newInputStream(
Paths.get(PrintAllTimeZones1.class.getResource("/input.xml").toURI())));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Templates xsltTemplate = transformerFactory.newTemplates(
new StreamSource(Files.newInputStream(
Paths.get(Application.class.getResource("/test.xslt").toURI()))));
final Transformer transformer = xsltTemplate.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, UTF_8.name());
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final StreamResult result = new StreamResult(out);
transformer.transform(source, result);
System.out.println(result.getOutputStream().toString());
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
}input.xml
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>test.xslt
<Test version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times">
<xsl:value-of select="date:date-time()"/>
</Test>build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-spring-boot'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile 'jaxen:jaxen'
testCompile("junit:junit")
compile group: 'xalan', name: 'xalan', version: '2.7.2'
compile group: 'xmlunit', name: 'xmlunit', version: '1.6'
compile group: 'org.apache.avro', name: 'avro', version: '1.9.0'
}发布于 2019-06-20 09:34:21
获得2019-06-20T10:23:31+05:1800000的原因是xalan的ExsltDatetime实现将添加GMT偏移量和DST偏移量(5.5个小时)。但是,在以小时&分钟计算偏移量时,xalan实现中似乎存在缺陷。
在xalan的ExsltDatetime类中偏移的代码
int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
// If there is no offset, we have "Coordinated
// Universal Time."
if (offset == 0)
buff.append('Z');
else {
// Convert milliseconds to hours and minutes
int hrs = offset/(60*60*1000);
// In a few cases, the time zone may be +/-hh:30.
int min = offset%(60*60*1000);
char posneg = hrs < 0? '-': '+';
buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min));
}上述代码以小时为5表示偏移量,这很好,但分钟偏移量计算为1800000,这是不正确的。
其他部分应正确计算剩余偏移量的记录,如下所示:
// Convert milliseconds to hours and minutes
int hrs = offset/(60*60*1000);
// In a few cases, the time zone may be +/-hh:30.
//get the remaining offset in ms
offset -= (hrs*60*60*1000);
//convert remaining offset into minutes
int min = offset/(60*1000);
char posneg = hrs < 0? '-': '+';
buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min));以上是经过修正的代码,它正确地返回分钟作为30分钟。
要在XSLT中为当前日期使用不同/简单的日期格式化程序,可以使用:
<Test version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="xalan://java.text.SimpleDateFormat"
xmlns:java="http://xml.apache.org/xslt/java">
<xsl:variable name="iso-date"
select='date:new("yyyy-MM-dd'T'hh:mm:ssXXX")' />
<xsl:value-of select="java:format($iso-date, java:java.util.Date.new())"/>
</Test>您也可以尝试XSLT2.0格式函数
https://stackoverflow.com/questions/56679556
复制相似问题