2016-07-04 143 views
1

我正在編輯聲明中的原始編碼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); 
} 

它的工作原理,但它似乎是一個醜陋的解決方案。如果有人知道更好的方法,我將非常感激。

+0

也許這可能會幫助你:http://stackoverflow.com/questions/3578395/java-xml-documentbuilder-setting-the-encoding-when-parsing – Berger

+0

@Berger謝謝你的提示。但是,我不認爲這解決了我的問題。 OutputFormat似乎被棄用,我已經使用了transformer.setOutputProperty(OutputKeys.ENCODING,encoding)。我想我需要編輯文檔的聲明,但我不知道該怎麼做。 – ostid

+0

這似乎應該工作('DocumentBuilder'應該尊重xml聲明)。這導致我認爲你的文檔可能不好。你能否檢查你的基文件是否真的是一個ASCII文件(不僅在它的XML序言中是這樣說的,但是如果你看實際的字節,這實際上是真的嗎?)。 – GPI

回答

0

我有一個類似的問題在我的XML聲明原是:

<?xml version="1.0" encoding="windows-1252"?> 

但解析到Document然後回到XMLUTF-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"?>