Java SAX变压器和线端在<;?xml&燃气轮机;

Java SAX变压器和线端在<;?xml&燃气轮机;,java,xml,sax,Java,Xml,Sax,要编写xml代码,我使用以下代码: import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; ... XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance(); XMLStreamWriter writer = xMLOutputFactory.createXMLStreamWriter(stringWriter)

要编写xml代码,我使用以下代码:

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
...
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xMLOutputFactory.createXMLStreamWriter(stringWriter);
writer.writeStartDocument("UTF-8", "1.0");
writer.writeCharacters("\n");
//I tried also writer.writeCharacters(System.getProperty("line.separator"));
writer.writeStartElement("settings");
...
public String transform(final String xml) throws XMLStreamException, TransformerException {
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    Writer writer = new StringWriter();
    transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(writer));
    return writer.toString();
}
要将单行xml转换为多行普通xml格式,我使用以下代码:

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
...
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xMLOutputFactory.createXMLStreamWriter(stringWriter);
writer.writeStartDocument("UTF-8", "1.0");
writer.writeCharacters("\n");
//I tried also writer.writeCharacters(System.getProperty("line.separator"));
writer.writeStartElement("settings");
...
public String transform(final String xml) throws XMLStreamException, TransformerException {
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    Writer writer = new StringWriter();
    transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(writer));
    return writer.toString();
}
这就是结果

<?xml version="1.0" encoding="UTF-8"?><settings>
   ...
</settings>

...

正如您看到的
一样,让我们假设您正在使用Java附带的内置XSLT处理器。这是一个XSLT1.0处理器,因此我们需要查看XSLT1.0规范

这是XSLT1.0关于indent=“yes”的说法:

如果indent属性的值为yes,则xml输出方法 除了结果树中的空白外,还可以输出空白 (可能基于源文档中的空白 或样式表),以便很好地缩进结果;如果缩进 属性的值为“否”,它不应输出任何附加值 空白。默认值为否。xml输出方法应使用 输出额外空白的算法,确保 结果如果要使用 [3.4空白剥离]中描述的过程 仅由xsl:text组成的保留空格的元素是 输出附加空白时的效果与输出附加空白时的效果相同 空白不是输出

这很复杂,但底线是处理器可能会在您想要的位置输出新行,但没有义务这样做

如果使用Saxon作为XSLT处理器,那么此时它会输出一个换行符

但你还没说为什么这条新线对你如此重要。你把没有它描述为一个“问题”,但为什么它是一个问题呢?如果使用标准XML解析器解析生成的文档,那么此时的任何换行符都将被忽略。有一种情况会有所不同,即您生成的XML用作合并到某个较大文档中的外部解析实体。但在这种情况下,您肯定不想要换行符(这可能就是Xalan不输出它的原因)


注意:另请参见用户这次在何处抱怨序列化输出中不需要的换行符。如果您关心同一文档的可选序列化之间的这种差异,这不会影响任何一致性解析器处理文档的方式,那么(a)您可能必须编写自己的序列化程序,(b)您将失去XML的一个主要好处,即大量一致性工具的可用性,以及(c) 您做错了:可能是使用了一个不一致的解析器(或者根本没有解析器)来处理生成的XML。

对我来说,它可以处理缩进和XML
standalone=“yes”


当然,这要求您的客户机或应用程序能够容忍独立声明。

说出您正在使用的XSLT处理器总是很有用的。(其中一个序列化参数是特定于Xalan的,这一事实提供了线索,但不是确凿的证据)@Michael Kay我添加了导入。或者我不明白你的意思。我没有提供必要的信息吗?好的,如果你不知道实现JAXP接口的XSLT处理器不止一个,那么你可能正在使用JDK附带的默认处理器,它有效地回答了这个问题。@Michael Kay我明白了。但它回答了你的问题是的,但不是我的:)。从您的个人资料中,我了解到您是xml专家。你能给点提示吗?我不明白为什么使用默认实现编写xml文件这样简单的任务会造成这样的问题。只有我有这样的问题?如何解决?非常感谢您提供如此详细的答案,但它没有给出解决方案。对我来说,这是一个问题的原因是我们客户的系统管理员说这是一个问题,这就是我必须解决它的原因。此外,应用程序必须生成许多不同的xml文件,这可能是他们想要普通xml文件的原因。我不是XML专家,在你发表文章之后,我不得不在Wiki上阅读XSLT和XSL。我一个都不需要!我只想从java对象字段将一些数据写入XML文件。这就是全部。你为什么在回答中提到XSLT处理器?很抱歉,但如果我们要帮助你解决这个问题,那么我们需要知道为什么这是一个问题。在这个论坛上,人们对XML的格式非常挑剔的最常见的原因是他们对XML的处理不正确(通常使用自制解析器),如果是这样的话,那么您必须顶住压力生成他们想要的特定格式,并鼓励他们正确处理XML。关于XML的全部要点是它是一个标准,只有生产者和消费者都遵守标准,您才能获得XML的好处。我们谈论XSLT的原因是您选择使用XSLT处理器来序列化XML数据。实际上,您并不是在使用XSLT本身,而是在利用XSLT处理器为您提供了对序列化的大量控制这一事实,尽管在您的例子中这还不够。在所有这些情况下,根元素都不在第一行(其中)。因此,客户的要求可以说是合理的。他们付钱,想要得到
normal
xml文件。正常并不是只遵循规范,而是对使用它的人来说是正常的和好的。