我正在編輯聲明中的原始編碼ASCII的xml文件。在生成的文件中,我希望編碼爲UTF-8,以編寫像åäö這樣的瑞典字符,這是我目前無法做到的。使用java編輯xml聲明編碼
與我的文件相當的示例文件可以在archivematica wiki找到。
在運行我的程序並帶有上述示例文件副本後得到的生成的SIP.xml文件可以在this link處獲得。帶有ääö文本的添加標籤位於文檔的最後。
正如下面的代碼所示,我已經嘗試在變換器上設置編碼,並試圖使用OutputStreamWriter來設置編碼。 最後,我將原始文件中的聲明編輯爲UTF-8,最後寫出了åäö。所以這個問題似乎是原始文件的編碼。如果我沒有弄錯,它不應該導致任何問題將聲明從ASCII更改爲UTF-8,問題是,我如何在我的程序中執行此操作?我可以在將它解析爲Document對象之後執行此操作,還是在解析之前需要執行某些操作?
package provklasser;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
*
* @author
*/
public class Provklass {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
File chosenFile = new File("myFile.xml");
//parsing the xml file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document metsDoc = builder.parse(chosenFile.getAbsolutePath());
Element agent = (Element) metsDoc.getDocumentElement().appendChild(metsDoc.createElementNS("http://www.loc.gov/METS/","mets:agent"));
agent.appendChild(metsDoc.createTextNode("åäö"));
DOMSource source = new DOMSource(metsDoc);
// write the content into xml file
File newFile = new File(chosenFile.getParent(), "SIP.xml");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
StreamResult result = new StreamResult(newFile);
//Writer out = new OutputStreamWriter(new FileOutputStream("SIP.xml"), "UTF-8");
//StreamResult result = new StreamResult(out);
transformer.transform(source, result);
} catch (ParserConfigurationException ex) {
Logger.getLogger(Provklass.class.getName()).log(Level.SEVERE, null, ex);
} catch (SAXException ex) {
Logger.getLogger(Provklass.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Provklass.class.getName()).log(Level.SEVERE, null, ex);
} catch (TransformerConfigurationException ex) {
Logger.getLogger(Provklass.class.getName()).log(Level.SEVERE, null, ex);
} catch (TransformerException ex) {
Logger.getLogger(Provklass.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
UPDATE: 使用metsDoc.getInputEncoding()返回UTF-8,而metsDoc.getXmlEncoding()返回ASCII。如果我在保存新文件並解析新文件後解析新文件,我會得到相同的結果。所以文件似乎有正確的編碼,但是xml聲明不正確。
現在我解析它,與parseXML(chosenFile.getAbsoutePath());
取代上述解析部分,並使用以下方法之前編輯XML爲文本文件:
private String withEditedDeclaration(String fileName) {
StringBuilder text = new StringBuilder();
try {
String NL = System.getProperty("line.separator");
try (Scanner scanner = new Scanner(new FileInputStream(fileName))) {
String line = scanner.nextLine();
text.append(line.replaceFirst("ASCII", "UTF-8") + NL);
while (scanner.hasNextLine()) {
text.append(scanner.nextLine() + NL);
}
}
} catch (FileNotFoundException ex) {
Logger.getLogger(MetsAdaption.class.getName()).log(Level.SEVERE, null, ex);
}
return text.toString();
}
private void parseXML(String fileName) throws SAXException, IOException, ParserConfigurationException {
String xmlString = withEditedDeclaration(fileName);
//parsing the xml file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlString));
metsDoc = builder.parse(is);
}
它的工作原理,但它似乎是一個醜陋的解決方案。如果有人知道更好的方法,我將非常感激。
也許這可能會幫助你:http://stackoverflow.com/questions/3578395/java-xml-documentbuilder-setting-the-encoding-when-parsing – Berger
@Berger謝謝你的提示。但是,我不認爲這解決了我的問題。 OutputFormat似乎被棄用,我已經使用了transformer.setOutputProperty(OutputKeys.ENCODING,encoding)。我想我需要編輯文檔的聲明,但我不知道該怎麼做。 – ostid
這似乎應該工作('DocumentBuilder'應該尊重xml聲明)。這導致我認爲你的文檔可能不好。你能否檢查你的基文件是否真的是一個ASCII文件(不僅在它的XML序言中是這樣說的,但是如果你看實際的字節,這實際上是真的嗎?)。 – GPI