2
votes

Is this valid using java syntax for xslt? I do not have an xml transformation tool that supports java for my validation so I'm not sure if the syntax is correct. If not could anyone please let me know if there is any other approach that I can take?

So if the RequestedDeliveryDate is less than current date then add 5 days to current date and that will be the new RequestedDeliveryDate.

XSLT im using:

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java">
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" /> 
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/tXML/Message/Order/OrderLines/OrderLine/ShippingInfo/RequestedDeliveryBy">
        <xsl:choose>
            <xsl:when test="(java:format(java:java.text.SimpleDateFormat.new('MM/dd/yyyy HH:mm'), java:java.util.Date.new()) &gt;= '.')">
                <RequestedDeliveryBy>
                    <xsl:value-of select="java:format(java:java.text.SimpleDateFormat.new('MM/dd/yyyy HH:mm'), java:java.util.Date.new(),5)" />
                </RequestedDeliveryBy>
            </xsl:when>             
            <xsl:otherwise>
                <xsl:value-of select="." />        
            </xsl:otherwise>    
        </xsl:choose>                        
    </xsl:template>
</xsl:stylesheet>

Test xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tXML>
    <Message>
        <Order> 
            <OrderLines> 
                <OrderLine>
                    <ShippingInfo> 
                        <RequestedDeliveryBy>12/04/2015 23:59</RequestedDeliveryBy>
                    </ShippingInfo>                  
                </OrderLine> 
            </OrderLines>
        </Order> 
    </Message>
</tXML>
1
ok added it in the question. ThanksMax

1 Answers

3
votes

You are trying to use XSLT 1.0 with Java and Xalan. Seeing date manipulation in XSLT makes me anxious. Date handling isn't really XSLT's strong suit. As you are already resigned to using a Java method let's make Java do the hard work.

I'm assuming you are programmatically invoking your transform (e.g. so Xalan can access the Java method that the XSLT references):

TransformerFactory tFactory
    = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource("Transform.xsl"));
transformer.transform(new StreamSource("Test.xml"),
    new StreamResult(new FileOutputStream("Out.xml")));

We can write a nice simple class to process your RequestDeliveryBy date.

I'm using Joda-Time here because it is easier than the old date-time classes bundled with early versions of Java. If you are using Java 8 or later you can instead use the new built-in java.time framework.

package com.example;

import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class ProcessDate {

    private static final String DATEPATTERN = "MM/dd/yyyy HH:mm";
    private static final DateTimeFormatter FMT = DateTimeFormat.forPattern(DATEPATTERN);

    public static String process(final String date) {  
        String result = date;
        LocalDateTime now = new LocalDateTime();
        LocalDateTime dt = LocalDateTime.parse(date, FMT);
        if (now.isAfter(dt)) {
            result = FMT.print(now.plusDays(5));
        }
        return result;
    }

}

So with Java doing all the heavy lifting your Transform.xsl becomes nice and simple:

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:java="http://xml.apache.org/xslt/java" 
                exclude-result-prefixes="java">
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" /> 
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/tXML/Message/Order/OrderLines/OrderLine/ShippingInfo/RequestedDeliveryBy">
        <RequestedDeliveryBy><xsl:value-of select="java:com.example.ProcessDate.process(string(.))"/></RequestedDeliveryBy>
    </xsl:template>
</xsl:stylesheet>