register
other register

Wednesday, May 14, 2008

Write Logs to Different Files Using Log4J

If you have one generic java program to transform xml files from different directory.

java -Dfile_properties=/path/to/file.properties -jar YourProgramm.jar

You can specify different file.properties input directory using the "-D" parameter in the command line.

In each file.properties file, you specify:

input_dir=/bla/bla
xslt_dir=/bla/bla
output_dir=/bla/bla
log4j_properties=/bla/bla

Because you might want different logs for different transformations from different source, thus you can spot on which source file cause the problem.

By default, if you don't specify where to load the log4j configurations, it will load the log4j.properties, and then log4j.xml from the class folder, which would be uneditable when put in a jar. This might not what you want. You want to specify an external log4j configuration which you can edit outside of the program.

Here is what you can do:

Put the xml log4j file (e.g. xmllog4jconfig.xml) in the project directory.

In your java program

Public class Transformer {

private static Logger logger = Logger.getLogger(SaxonTransform.class);

public static void main(String[] args) {

DOMConfigurator.configure("xmllog4jconfig.xml");
logger.debug("Here is some DEBUG");
logger.info("Here is some INFO");
logger.warn("Here is some WARN");
logger.error("Here is some ERROR");
logger.fatal("Here is some FATAL");
}
}    


In the log4j xml configuration file, you can use LevelRange filter to log different levels of information into different log files like below:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>

<!-- log without a filter -->
<appender name="file"
class="org.apache.log4j.FileAppender">
<param name="File" value="logs/test.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />
</layout>
</appender>

<!-- log with a filter -->
<appender name="debugfile"
class="org.apache.log4j.FileAppender">
<param name="File" value="logs/debug.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />
</layout>

<!-- set the filter -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="debug" />
<param name="LevelMax" value="debug" />
</filter>
</appender>

<root>
<priority value="debug"></priority>
<appender-ref ref="debugfile" />
<appender-ref ref="file" />
</root>
</log4j:configuration>


For more tutorials on Log4J, please have a look at:

Log4J Tutorial from The University Of Birmingham
Log4J Tutorial from Laliluna

Tuesday, May 06, 2008

Encoding in XSLT

If you have an xml document which contains German or French characters, then in your xml declarations, you should write:

<?xml version="1.0" encoding="ISO-8859-1"?>

Don't put "UTF-8" for it. It will not work

When using Java to write an xml fie, do the following:


File f = new File("newFile.xml");
FileOutputStream fos = new FileOutputStream(f);
OutputStreamWriter osw = new OutputStreamWriter(fos, Charset.forName("ISO-8859-1"));

// Begin to write an xml file.
osw.append("..");


Otherwise, if use the FileWriter instead of OutputStreamWriter, the programme will use the system default encoding which cause problems if the xml file contains German or French characters.

Remove unwanted namespace in XSLT

If we have the xslt like below:


<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:abc="http://www.abc.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<content>
...
</content>

</xsl:stylesheet>


The result xml will be look like:


<conent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.polopoly.com/polopoly/cm/xmlio"
xmlns:abc="http://www.abc.com">
...
</conent>


The namespaces in the tag are not what we want. We can remove these namespaces by using

exclude-result-prefixes="xsl abc xsi" in the xsl:stylesheet declaration.