In my earlier article, I have shown you how to transform a XML from one format to another format.
Below, I will show you how to refer to a Java class from an XSL.
This is the java class which I want to refer to the xsl file. And getDemoProperties() is the method name which I will call from XSL. This is nothing but to get a properties flag value from the properties file.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class DemoProperties {
Properties props;
static String fName = "./DemoProperties.properties";
public DemoProperties() {
props = new Properties();
try {
props.load(new FileInputStream(fName));
} catch (FileNotFoundException fnfEx){
fnfEx.printStackTrace();
}
catch (IOException ioEx){
ioEx.printStackTrace();
}
}
public String getDemoProperties(String propName) {
String retProp=new String("");
try {
retProp = props.getProperty(propName);
} catch(Exception e) {
e.printStackTrace();
}
return retProp;
}
}
DemoProperties.properties entry.
id=ID1
Input XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Order>
<CustomerID>0123456789</CustomerID>
<Title>Mr</Title>
<FirstName>Vicky</FirstName>
<Initial>VV</Initial>
<Surname>Verma</Surname>
<TelephoneNumber>0987654321</TelephoneNumber>
<SubPremise>RakhsakNagar</SubPremise>
<BuildingName>RakhsakNagar</BuildingName>
<StreetNumber>207</StreetNumber>
<StreetName>KharadiByPass</StreetName>
<Locality>Kharadi</Locality>
<PostTown>Pune</PostTown>
<County>Pune</County>
<Postcode>411014</Postcode>
<OrderDate>20052009 15:18:11</OrderDate>
<CADDate>05062009 15:23:54</CADDate>
<OrderReference>022-123456789</OrderReference>
<DealerChannel>Airtel Voice</DealerChannel>
<InstallationType>Self</InstallationType>
<AssetDescription>Airtel TV</AssetDescription>
<Action>Add</Action>
<ReplacementType>Active</ReplacementType>
<CurrentDate>20090611T11:15:08</CurrentDate>
</Order>
Sample XSL file:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rf="DemoProperties">
<xsl:strip-space elements="*" />
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes" />
<xsl:template match="Order">
<OrderForProduct xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:variable name="props" select="rf:new()" />
<xsl:variable name="var">
<xsl:value-of select="rf:getCPSProperties($props, 'id')" />
</xsl:variable>
<UniqueKey>
<xsl:attribute name="Id">
<xsl:value-of select="$var" />
</xsl:attribute>
</UniqueKey>
<ProductsDetails>
<Product Name="Airtel_TV" />
</ProductsDetails>
<PriorSubmission>
<xsl:attribute name="UserName">AirtelUser</xsl:attribute>
<xsl:attribute name="SubmitterRef">
<xsl:value-of select="OrderReference" />
</xsl:attribute>
</PriorSubmission>
</OrderForProduct>
</xsl:template>
</xsl:stylesheet>
XMLTransformation.java – Java class which actually does the transformation
import java.io.File;
import java.io.FileOutputStream;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
public class XMLTransformation {
XMLTransformation() {
}
private static void applyTransformAndSave() {
try {
String sampleInputXML= "SampleInputXML.xml";
File sampleInputFile = new File(sampleInputXML);
String sampleOutputXML = "SampleOutputFile.xml";
//Convert input file to output batch file according to the XSL
TransformerFactory tFactory1 = TransformerFactory.newInstance();
Transformer transformer1;
transformer1 = tFactory1.newTransformer(new StreamSource("SampleXSL.xsl"));
transformer1.setOutputProperty(OutputKeys.INDENT, "yes");
transformer1.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer1.transform(new StreamSource(sampleInputFile), new StreamResult(new FileOutputStream(sampleOutputXML)));
} catch (TransformerConfigurationException tCEx){
tCEx.printStackTrace();
} catch (TransformerException tEx){
tEx.printStackTrace();
} catch(Exception ex){
ex.printStackTrace();
}
}
public static void main(String args[]) {
XMLTransformation xmlTransformation = new XMLTransformation();
XMLTransformation.applyTransformAndSave();
}
}
Output XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<OrderForProduct xmlns:rf="DemoProperties" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UniqueKey Id="ID1" />
<ProductsDetails>
<Product Name="Airtel_TV" />
</ProductsDetails>
<PriorSubmission UserName="AirtelUser" SubmitterRef="022-123456789" />
</OrderForProduct>
2 comments:
Hi.
I am curious about the security concerning this. Do you know how it is possible to allow that a specific class can be used?
Because in theory, someone could add:
xmlns:java="java"
to the namespaces and then:
<xsl:value-of select="java:lang.System.exit(0)" />
Which basically quits your application. Meaning, that XSL can now contain malicious code.
I know "XMLConstants.FEATURE_SECURE_PROCESSING" denies all calls to Java method, but have you stumbled across a way to add rules?
Post a Comment