Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The trick is to "mark" the Reader. If your reader does not support marking you can wrap it in a BufferedReader which does:</p> <ul> <li><a href="http://download.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#markSupported%28%29" rel="nofollow">http://download.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#markSupported%28%29</a></li> </ul> <p><strong>OPTION #1 - Check for BOM and Remove It</strong></p> <p>I believe my original code was writing the BOM incorrectly. The source code below makes more sense:</p> <pre><code>import java.io.*; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; public class Demo { private static char[] UTF32BE = {0x00, 0x00, 0xFE, 0xFF}; private static char[] UTF32LE = {0xFF, 0xFE, 0x00, 0x00}; private static char[] UTF16BE = {0xFE, 0xFF}; private static char[] UTF16LE = {0xFF, 0xFE}; private static char[] UTF8 = {0xEF, 0xBB, 0xBF}; public static void main(String[] args) throws Exception { // Create an XML document with a BOM FileOutputStream fos = new FileOutputStream("bom.xml"); writeBOM(fos, UTF16LE); OutputStreamWriter oswUTF8 = new OutputStreamWriter(fos, "UTF-8"); oswUTF8.write("&lt;root/&gt;"); oswUTF8.close(); // Create a Source based on a Reader to simulate source.getRequest() StreamSource attachment = new StreamSource(new FileReader(new File("bom.xml"))); // Wrap reader in BufferedReader so it will support marking Reader reader = new BufferedReader(attachment.getReader()); // Remove the BOM removeBOM(reader); TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.transform(new StreamSource(reader), new StreamResult(System.out)); } private static void writeBOM(OutputStream os, char[] bom) throws Exception { for(int x=0; x&lt;bom.length; x++) { os.write((byte) bom[x]); } } private static void removeBOM(Reader reader) throws Exception { if(removeBOM(reader, UTF32BE)) { return; } if(removeBOM(reader, UTF32LE)) { return; } if(removeBOM(reader, UTF16BE)) { return; } if(removeBOM(reader, UTF16LE)) { return; } if(removeBOM(reader, UTF8)) { return; } } private static boolean removeBOM(Reader reader, char[] bom) throws Exception { int bomLength = bom.length; reader.mark(bomLength); char[] possibleBOM = new char[bomLength]; reader.read(possibleBOM); for(int x=0; x&lt;bomLength; x++) { if(bom[x] != possibleBOM[x]) { reader.reset(); return false; } } return true; } } </code></pre> <p><strong>OPTION #2 - Find '&lt;' and Advance Reader to that Point</strong></p> <p>Read until you hit the '&lt;' leveraging mark/reset:</p> <pre><code>import java.io.*; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; public class Demo2 { private static char[] UTF32BE = {0x00, 0x00, 0xFE, 0xFF}; private static char[] UTF32LE = {0xFF, 0xFE, 0x00, 0x00}; private static char[] UTF16BE = {0xFE, 0xFF}; private static char[] UTF16LE = {0xFF, 0xFE}; private static char[] UTF8 = {0xEF, 0xBB, 0xBF}; public static void main(String[] args) throws Exception { // Create an XML document with a BOM FileOutputStream fos = new FileOutputStream("bom.xml"); writeBOM(fos, UTF16BE); OutputStreamWriter oswUTF8 = new OutputStreamWriter(fos, "UTF-8"); oswUTF8.write("&lt;root/&gt;"); oswUTF8.close(); // Create a Source based on a Reader to simulate source.getRequest() StreamSource attachment = new StreamSource(new FileReader(new File("bom.xml"))); // Wrap reader in BufferedReader so it will support marking Reader reader = new BufferedReader(attachment.getReader()); // Remove the BOM removeBOM(reader); TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.transform(new StreamSource(reader), new StreamResult(System.out)); } private static void writeBOM(OutputStream os, char[] bom) throws Exception { for(int x=0; x&lt;bom.length; x++) { os.write((byte) bom[x]); } } private static Reader removeBOM(Reader reader) throws Exception { reader.mark(1); char[] potentialStart = new char[1]; reader.read(potentialStart); if('&lt;' == potentialStart[0]) { reader.reset(); return reader; } else { return removeBOM(reader); } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload