XML2Ascii- XML tartalom tárolása csak ASCII karakterekkel
A probléma: Adott XML struktúrát olyan módon szerializálni, hogy az csak ASCII karaktereket tartalmazzon, de bármilyen szabványos XML parser által beolvasható maradjon.
Munka közben egy UTF-8 kódolású XML állományt olyan LDAP-ban kellet tárolni, amely csak iso-8859-1 karaktereket engedett meg. Különböző okoknál fogna sem a karaterkészlet átalakítás, sem a Base64-ben való tárolás nem jöhetett szóba. Az numerikus escape-szekvenciák XML-nél is a segítségünkre siettek, de különös problémát jelentettek a CDATA szekciók, amelyekben nem lehet escape szekvenciákkal helyettesíteni a problémás karaktereket. A triviális megoldás egy XSLT azonossági transzformáció lett volna, viszont ez nem tette lehetővé a CDATA szekciók érzékelését és megtartását, amitől az adott helyzetben nem lehetett eltekinteni.
A DOM struktúra minimális módosításával végzi el a feladatot ez a néhány soros osztály. A megoldás szépsége az egyszerűségben lakozik.
package hu.lithium.xml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import javax.xml.transform.OutputKeys;
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;
public class XML2Ascii {
public static final String help = "usage: java -jar xml2ascii.jar <input.xml> [<output.xml>]\nReplace all non-ASCII characters with NCRs while doing minimal modification to the document (e.g. splitting CDATA sections)";
public static void main(String[] args) {
if (args.length < 1) {
System.err.println(help); System.exit(1);
}
InputStream input = System.in;
PrintStream output = System.out;
try {
input = new FileInputStream(args[0]);
} catch (FileNotFoundException e1) {
System.err.println("[error] unable to open input file '"+args[0]+"', using stdin instead.");
}
if (args.length > 1) {
try {
output = new PrintStream(args[1]);
} catch (FileNotFoundException e) {
System.err.println("[error] unable to open output file '"+args[1]+"', using stdout instead.");
}
}
try {
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.ENCODING, "us-ascii");
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
output.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
t.transform(new StreamSource(input), new StreamResult(output));
} catch (TransformerException e) {
System.err.println("[fatal] unable to transform XML");
e.printStackTrace();
}
}
}