Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
因为移动到Java1.7XML文档元素不会缩进_Java_Xml_Parsing_Dom_Transform - Fatal编程技术网

因为移动到Java1.7XML文档元素不会缩进

因为移动到Java1.7XML文档元素不会缩进,java,xml,parsing,dom,transform,Java,Xml,Parsing,Dom,Transform,我正在尝试缩进Transformer生成的XML。 除第一个节点(文档元素)外,所有DOM节点都按预期缩进。 document元素不在新行中开始,只在XML声明的后面加上concat 当我迁移到Java1.7时,这个bug就出现了,而当我使用Java1.6或1.5时,它就不会发生了 我的代码: ByteArrayOutputStream s = new OutputStreamWriter(out, "utf-8"); TransformerFactory tf = TransformerFa

我正在尝试缩进Transformer生成的XML。 除第一个节点(文档元素)外,所有DOM节点都按预期缩进。 document元素不在新行中开始,只在XML声明的后面加上concat

当我迁移到Java1.7时,这个bug就出现了,而当我使用Java1.6或1.5时,它就不会发生了

我的代码:

ByteArrayOutputStream s = new OutputStreamWriter(out, "utf-8");

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4");

transformer.transform(new DOMSource(doc), new StreamResult(s));
输出:

<?xml version="1.0" encoding="UTF-8"?><a>
       <b>bbbbb</b>
 </a>
它按预期工作,但xml声明已更改, 它现在也有独立属性,我不想更改xml声明

好的

我在Java API中发现:

如果指定了doctype系统属性,xml输出方法应该在第一个元素之前输出文档类型声明

所以我用了这个属性

 transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
它解决了我的问题,没有改变我的xml声明


谢谢。

这似乎是Java中XML实现的一个问题(bug)。在XML声明之后获取换行符的唯一方法是显式指定
standalone
属性。您可以将其设置为
no
,这是隐式默认值,即使它在不使用DTD时完全不相关。

Xalan在某个点上更改了XML声明后换行符的行为

OpenJDK(因此也包括Oracle JDK)已经为这个问题实现了一个解决方案。可以通过在
Transformer
对象上设置特殊属性来启用此解决方法:

try {
    transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes");
} catch (IllegalArgumentException e) {
    // Might be thrown by JDK versions not implementing the workaround.
} 

这样,旧的行为(在XML声明后打印换行符)在不向XML声明添加独立属性的情况下还原。对我来说,在写入XML并告诉转换器忽略声明之前,将XML声明写入
编写器
OutputStream
。保持间距的唯一其他解决方案似乎是VTD-XML库

    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"").append(doc.getXmlVersion()).append("\"");
    sb.append(" encoding=\"").append(doc.getXmlEncoding()).append("\"");
    if (doc.getXmlStandalone()) {
        sb.append(" standalone=\"").append("" + doc.getXmlStandalone()).append("\"");
    }
    sb.append("?>").append("\n");

    writer.write(sb.toString());
            TransformerFactory tf = TransformerFactory.newInstance();
    try {
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    }
    catch (Exception e)  {
    //snipped out for brevity
    }
StringBuilder sb=新建StringBuilder();
某人追加(“”)。追加(“\n”);
写(某人写的东西);
TransformerFactory tf=TransformerFactory.newInstance();
试一试{
变压器=tf.新变压器();
setOutputProperty(OutputKeys.OMIT_XML_声明,“yes”);
}
捕获(例外e){
//剪短
}

这几天一直在寻找:)这对我来说不起作用。设置only DOCTYPE_PUBLIC=yes不会使文档元素从新行开始。只有STANDALONE=yes或no会执行此操作,但我不想显式指定它,因为我不使用DTD,而是使用模式。
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"").append(doc.getXmlVersion()).append("\"");
    sb.append(" encoding=\"").append(doc.getXmlEncoding()).append("\"");
    if (doc.getXmlStandalone()) {
        sb.append(" standalone=\"").append("" + doc.getXmlStandalone()).append("\"");
    }
    sb.append("?>").append("\n");

    writer.write(sb.toString());
            TransformerFactory tf = TransformerFactory.newInstance();
    try {
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    }
    catch (Exception e)  {
    //snipped out for brevity
    }