我正在编辑声明中带有原始编码ASCII的xml文件。在结果文件中,我希望编码为UTF-8,以便编写像åäö这样的瑞典字符,这是我目前无法做到的。
可以在archivematica wiki找到与我的文件等效的示例文件。
我可以在this link访问我在运行程序后得到的SIP.xml文件,其中包含上述示例文件的副本。带有åäö文本的添加标签位于文档的最后。
如下面的代码所示,我尝试在变换器上设置编码,并尝试使用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);
}
}
}
更新: 使用metsDoc.getInputEncoding()返回UTF-8,而metsDoc.getXmlEncoding()返回ASCII。如果我在保存后解析新文件并创建一个新文档,我会得到相同的结果。因此该文档似乎具有正确的编码,但xml声明不正确。
现在我在解析之前将xml编辑为文本文件,用parseXML(chosenFile.getAbsoutePath());
替换上面的解析部分并使用以下方法:
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);
}
它有效,但它似乎是一个丑陋的解决方案。如果有人知道更好的方式,我将非常感激。
答案 0 :(得分:0)
我有一个类似的问题,我的xml声明最初是:
<?xml version="1.0" encoding="windows-1252"?>
但是在解析为Document
然后再回到XML
UTF-8
之后,编码保持为windows-1252
,即使字节本身位于UTF-8
。我最终得出结论TransformerFactory
的实现是com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
,将其更改为:
org.apache.xalan.processor.TransformerFactoryImpl
来自Apache Xalan Java 2.7.1的导致XML减速中的字符集被正确设置,现在我有:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>