在根节点之前在xml文件中添加换行符

问题描述:

我正在尝试在XML文档中的根节点之上的注释之后添加换行符。在根节点之前在xml文件中添加换行符

我需要的是这样的:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!--DO NOT EDIT THIS FILE--> 
<projects> 
</projects> 

,但我能得到的是这个(根内线突破,但我需要的注释后换行):

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!--DO NOT EDIT THIS FILE--><projects> 

</projects> 

我需要在我的评论之后添加换行符。有没有办法做到这一点?

我的代码:

import java.io.File; 
import java.io.FileInputStream; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Comment; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.Text; 

public class XMLNewLine { 
    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     System.out.println("Adding comment.."); 

     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 

     dbf.setValidating(false); 
     DocumentBuilder db; 

     try { 
      Document doc; 
      StreamResult result; 
      result = new StreamResult(new File("abc.xml")); 
      db = dbf.newDocumentBuilder(); 
      doc = db.parse(new FileInputStream(new File("abc.xml"))); 

      Element element = doc.getDocumentElement(); 
      Text lineBreak = doc.createTextNode("\n"); 

      element.appendChild(lineBreak); 
      Comment comment = doc 
        .createComment("DO NOT EDIT THIS FILE"); 
      element.getParentNode().insertBefore(comment, element); 
      doc.getDocumentElement().normalize(); 
      TransformerFactory transformerFactory = TransformerFactory 
        .newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(); 
      DOMSource source = new DOMSource(doc); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      transformer.transform(source, result); 

     } catch (Exception e) { 
      // TODO Auto-generated catch block 

     } 

    } 
} 
+2

*“我试图XML文档中的根节点我上面的评论后添加换行符。” * - 为什么地球上你想这样做吗? – Tomalak

+0

(不要回答,这是一个反问的问题,我明白这纯粹是出于美观的原因,我也不是说这不可能) – Tomalak

+1

@tomalak感谢您的回复。这是为了确保文件在发货之前看起来很好并且可读。 –

你基本上要包含注释节点后换行文本节点。

Element docElem = doc.getDocumentElement(); 

doc.insertBefore(doc.createComment("DO NOT EDIT THIS FILE"), docElem); 
doc.insertBefore(doc.createTextNode("\\n"), docElem); 


编辑:看来即使追加空格只有文本节点在org.w3c.dom.Document的根节点是不允许的。这是100%正式正确的,但也是无益的。

注释在Transformer的输出中呈现的方式取决于它使用的序列化程序(HTML,XML和纯文本输出有不同的序列化程序)。在内置的XML序列化器中,评论的结尾被定义为--> - 没有换行符。

由于javax.xml.transform.Transformer的内部是硬连线的,串行器不是公共API并且该类被标记为final,因此覆盖该行为或设置自定义串行器是不可能的。

换句话说,你运气不好,在干净的方式中加入你的换行符。

你可以,但是,安全地添加一个稍微不洁方式:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 

FileInputStream inputXml = new FileInputStream(new File("input.xml")); 
Document doc = db.parse(inputXml); 

// add the comment node  
doc.insertBefore(doc.createComment("THIS IS A COMMENT"), doc.getDocumentElement()); 

StringWriter outputXmlStringWriter = new StringWriter(); 
Transformer transformer = transformerFactory.newTransformer(); 
// "xml" + "UTF-8" "include XML declaration" is the default anyway, but let's be explicit 
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
transformer.transform(new DOMSource(doc), new StreamResult(outputXmlStringWriter)); 

// now insert our newline into the string & write an UTF-8 file 
String outputXmlString = outputXmlStringWriter.toString() 
    .replaceFirst("<!--", "\n<!--").replaceFirst("-->", "-->\n"); 

FileOutputStream outputXml = new FileOutputStream(new File("output.xml"));    
outputXml.write(outputXmlString.getBytes("UTF-8")); 

上做XML字符串搜索和替换操作一般是高度气馁,但在这种情况下,很少有能出错。

+0

我得到低于错误 ** _ org.w3c.dom.DOMException:HIERARCHY_REQUEST_ERR:尝试插入不允许的节点。 _ ** 何时使用以下代码: 'doc.insertBefore(doc.createTextNode(“\\ n”),docElem);' –

+0

@Murali请参阅修改后的答案。 – Tomalak

因为我有同样的问题,在一段时间后重新审视。我发现了另一个解决方案,不需要缓冲输出的字符串:

  1. 只写了XML声明通过传递一个空文件。这也会附加一个换行符。

  2. 写而不XML声明文档内容

代码:

StreamResult streamResult = new StreamResult(writer); 
// output XML declaration with an empty document 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
transformer.transform(new DOMSource(), streamResult); 
// output the document without XML declaration 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
transformer.transform(new DOMSource(doc), streamResult); 

您可以通过不加注释节点到文档实现这一目标,而是部分地改变你的文件。首先改变你自己的XML处理指令,并分别发表意见,然后文档的其余部分:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(new FileInputStream(new File("abc.xml"))); 

Result output = new StreamResult(new File("abc.xml")); 
Source input = new DOMSource(doc); 


// xml processing instruction and comment node 
ProcessingInstruction xmlpi = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\""); 
Comment comment = doc.createComment("DO NOT EDIT THIS FILE"); 

// first transform the processing instruction and comment 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
transformer.transform(new DOMSource(xmlpi), output); 
transformer.transform(new DOMSource(comment), output); 
// then the document 
transformer.transform(input, output);