从生成的XML中删除“standalone =”yes“”。

87

您知道有没有JAXB设置可防止在生成的XML中出现standalone="yes"吗?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

7
为什么那是一个问题? - Kornel
1
@Kornel,在我的项目中,为了熟悉Tibco和WebMethod,它会生成错误,因为standalone=yes未被识别。 - aswzen
13个回答

124

JAXB是JDK1.6的一部分。

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

17
这个操作没有得到预期的结果。它删除了所有XML声明行。我只想删除XML声明中的“standalone”属性。 - Nicolas Barbulesco
1
如果你想知道为什么这对你不起作用,就像我一样,那么答案是,效果取决于您使用哪个marshal api 。 对于marshal(Object,Outputstream)和marshal(Object,Writer),这按照此处建议的方式工作。 对于marshal(Object,Node),它没有任何影响。 对于其余的marshal api含义,请查看这里下的Supported Properties部分。 - Lasse Samson
不支持Java 11。整个片段 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 将被删除。 - Andriy

68

你可以使用

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
或者
marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false)

禁用默认的XML声明,然后添加您自定义的XML声明。

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

marshaller.setProperty("com.sun.xml.bind.xmlHeaders",
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

将生成的XML中的standalone="yes"属性去除,以避免它成为生成的XML的一部分。


2
"setProperty" 中的 "xmlDeclaration" 在运行时出现异常。 - Nicolas Barbulesco
2
"setProperty"行中的"xmlHeaders"也失败了。PropertyException。所以这不是一个解决方案。 - Nicolas Barbulesco
你使用的是哪个版本的Java和JAXB? - WarFox
@WarFox,使用xmlHeaders命令的setProperty在jdk1.6.0_24和JAXB版本2.1中无法正常工作。 - Bryan Larson
3
无论是Java6还是Java7,我都必须添加"internal",即marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");。 - Caoilte
不支持Java 11。整个片段 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 将消失。 - Andriy

68

这个属性:

marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false);

...可以用来实现无:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

然而,我不认为这是最佳实践。


2
谢谢,这正是我所需要的。我同意包括该行是最佳实践,但我正在与一个不期望它的Web服务进行接口交互。 - jgrowl
6
很好它能运作,但顺带一提,如果服务无法接受合法的XML,那么该服务就是有问题的,因此最好向其提交一个缺陷报告。 - StaxMan
4
在JDK1.6中无法使用JAXB。请查看so_mv的答案以获得正确的解决方案。 - sversch
1
飞行中发生异常:异常。 - Nicolas Barbulesco
1
@sversch:你可以尝试使用属性类:"com.sun.xml.internal.bind.xmlHeaders"。 - bora.oren
1
@baybora.oren 在Java 1.7.0_51上,"com.sun.xml.internal.bind.xmlHeaders"也会出现javax.xml.bind.PropertyException的错误。 - Phil

7
如果有人仍在解决这个问题,你可以考虑使用以下内容。
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

为了移除所有XML声明并在输出流或方法的开头编写自己的字符串,您可以:

6
如果您使文档依赖于DOCTYPE(例如使用命名实体),则它将停止独立,因此在XML声明中将不允许使用standalone ="yes"。但是,独立的XML可以在任何地方使用,而非独立的XML对于不加载外部的XML解析器存在问题。我不认为这个声明会有什么问题,除了与不支持XML的软件以及一些可怕的正则表达式混合使用时可能存在互操作性问题。

1
准确地说,任何声称处理xml的系统却在xml声明处出现错误似乎都是非常可疑的。 - StaxMan
2
它以何种方式回答了这个问题? - ᄂ ᄀ
1
如何使文档依赖于“DOCTYPE”? - Lii

5
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

这对我有用,适用于JDK1.7。可以删除standalone=\"no\"以获得其余xml部分。

1
错误:javax.xml.bind.PropertyException:名称:com.sun.xml.internal.bind.xmlHeaders 值:<?xml version="1.0" encoding="UTF-8"?> - aswzen

5

如果您仅使用默认的javax.xml包,则可以将marshaller的JAXB_FRAGMENT选项设置为“true”(这会省略默认的xml处理指令),然后使用XMLStreamWriter的writeProcessingInstruction方法插入自己的指令:

xmlStreamWriter.writeProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
jaxbMarshaller.setProperty( Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.marshal(object, xmlStreamWriter);
xmlStreamWriter.writeEndDocument();

3

我正在使用Java 1.8和JAXB 2.3.1

首先,确保在pom.xml中使用的是Java 1.8版本。

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

然后在源代码中,我使用了以下内容:(关键是内部部分)

// remove standalone=yes
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

3

只是尝试

private String marshaling2(Object object) throws JAXBException, XMLStreamException {
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    StringWriter writer = new StringWriter();
    writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    jaxbMarshaller.marshal(object, writer);
    return writer.toString();
  }

很酷,可以在Java 11上工作。 - Andriy

2
你可以使用以下代码: marshaller.setProperty("jaxb.fragment", Boolean.TRUE);
这段代码适用于Java 8。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接