Ésta trabaja para varias codificaciones, teniendo en refieren tanto a la lista de materiales y la declaración XML. Por defecto es UTF-8
si no se aplica:
String encoding;
FileReader reader = null;
XMLStreamReader xmlStreamReader = null;
try {
InputSource is = new InputSource(file.toURI().toASCIIString());
XMLInputSource xis = new XMLInputSource(is.getPublicId(), is.getSystemId(), null);
xis.setByteStream(is.getByteStream());
PropertyManager pm = new PropertyManager(PropertyManager.CONTEXT_READER);
for (Field field : PropertyManager.class.getDeclaredFields()) {
if (field.getName().equals("supportedProps")) {
field.setAccessible(true);
((HashMap<String, Object>) field.get(pm)).put(
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY,
new XMLErrorReporter());
break;
}
}
encoding = new XMLEntityManager(pm).setupCurrentEntity("[xml]".intern(), xis, false, true);
if (encoding != "UTF-8") {
return encoding;
}
// From @matthias-heinrich’s answer:
reader = new FileReader(file);
xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(reader);
encoding = xmlStreamReader.getCharacterEncodingScheme();
if (encoding == null) {
encoding = "UTF-8";
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new UndeclaredThrowableException(e);
} finally {
if (xmlStreamReader != null) {
try {
xmlStreamReader.close();
} catch (XMLStreamException e) {
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
return encoding;
probado en Java 6 con:
UTF-8
archivo XML con la lista de materiales, la declaración XML ✓
UTF-8
archivo XML sin BOM, la declaración XML ✓
UTF-8
Archivo XML con lista de materiales, sin declaración XML ✓
UTF-8
Archivo XML sin lista de materiales, sin XML Declaración ✓
ISO-8859-1
archivo XML (sin BOM), la declaración XML ✓
UTF-16LE
archivo XML con la lista de materiales, sin declaración XML ✓
UTF-16BE
archivo XML con la lista de materiales, sin declaración XML ✓
Permanente sobre los hombros de estos gigantes:
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.xml.stream.*;
import org.xml.sax.*;
import com.sun.org.apache.xerces.internal.impl.*;
import com.sun.org.apache.xerces.internal.xni.parser.*;
'org.w3c.dom.Document.getXmlEncoding()' ?? – artbristol
Aunque esto es antiguo: hay una declaración oficial del W3C: https://www.w3.org/TR/xml/#sec-guessing –