我正在尝试在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
}
}
}
答案 0 :(得分:7)
你基本上想要一个包含注释节点后换行符的文本节点。
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
,因此无法覆盖该行为或设置自定义序列化程序。
换句话说,如果以 clean 的方式添加换行符,你就不幸了。
但是,您可以安全地以稍微不干净的方式添加它:
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字符串执行搜索和替换操作是非常不鼓励的,但在这种情况下,几乎没有什么可以出错。
答案 1 :(得分:2)
一段时间之后重新审视这个问题,因为我遇到了同样的问题。我找到了另一个不需要在String中缓冲输出的解决方案:
通过传递空文档来仅写入XML声明。这也会附加一个换行符。
编写没有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);
答案 2 :(得分:0)
您可以通过不在文档中添加注释节点来实现此目的,而是部分转换文档。首先分别转换您自己的XML处理指令和注释,然后转换文档的其余部分:
$ANDROID_HOME
答案 3 :(得分:0)
有JDK bug这个问题。它没有固定(如你所料),因为这可能会给用户造成许多问题。现有的申请。
添加以下输出属性修复了此问题:
transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes");
答案 4 :(得分:0)
有同样的问题。 我通过将注释放在根元素中来解决了这一问题。 不完全相同,但我认为可以接受。