當第一次解組,然後編組對象時,當前對象具有@XmlAnyElement
屬性時,我正面臨一個奇怪的JAXB名稱空間行爲。避免anyElement上重複的名稱空間定義
這裏的設置:
package-info.java
@XmlSchema(
namespace = "http://www.example.org",
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = { @javax.xml.bind.annotation.XmlNs(prefix = "example", namespaceURI = "http://www.example.org") }
)
類型定義:
@XmlRootElement
@XmlType(namespace="http://www.example.org")
public class Message {
private String id;
@XmlAnyElement(lax = true)
private List<Object> any;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Object> getAny() {
if (any == null) {
any = new ArrayList<>();
}
return this.any;
}
}
和測試代碼本身:
@Test
public void simpleTest() throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Message.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
String xml =
"<example:message xmlns:example=\"http://www.example.org\" xmlns:test=\"http://www.test.org\" xmlns:unused=\"http://www.unused.org\">\n" +
" <example:id>id-1</example:id>\n" +
" <test:value>my-value</test:value>\n" +
" <test:value>my-value2</test:value>\n" +
"</example:message>";
System.out.println("Source:\n"+xml);
// parsed
Object unmarshalled = unmarshaller.unmarshal(new StringReader(xml));
// directly convert it back
StringWriter writer = new StringWriter();
marshaller.marshal(unmarshalled, writer);
System.out.println("\n\nMarshalled again:\n"+writer.toString());
}
的問題這個設置是將所有「未知」名稱空間重複添加到任何元素。
<example:message xmlns:example="http://www.example.org" xmlns:test="http://www.test.org" xmlns:unused="http://www.unused.org">
<example:id>id-1</example:id>
<test:value>my-value</test:value>
<test:value>my-value2</test:value>
</example:message>
變成這樣:
<example:message xmlns:example="http://www.example.org">
<test:value xmlns:test="http://www.test.org" xmlns:unused="http://www.unused.org">my-value</test:value>
<test:value xmlns:test="http://www.test.org" xmlns:unused="http://www.unused.org">my-value2</test:value>
<example:id>id-1</example:id>
</example:message>
因此,我怎樣才能避免這種情況!爲什麼不像在輸入xml中一樣在根元素中定義一次命名空間?由於anyElement的命名空間並不是先前已知的,因此無法通過程序包定義註冊它...
此外,是否還有可能將未使用的命名空間剝離(按需)?
哇。很好的答案。謝謝! XSLT方法看起來很誘人,但我認爲與未知名稱空間一起,這可能會變得非常難看......自定義映射器會很好,但不幸的是我沒有使用參考實現(僅僅是痛苦的JDK沒有縮影)。因此我認爲我必須忍受醜陋。 *一個*最後一個問題:爲什麼在步驟2中添加了「未使用的」NS?不需要......編組人員只是添加所有的_remaining_命名空間,因爲它不知道會發生什麼? – Ingo
@Ingo如果您使用的是標準的Java發行版,那麼您可能已經使用了參考實現。當然,爲了真正能夠在內部命名空間中導入類,您需要一些依賴性,但可以將其視爲「提供」。至於「未使用」的命名空間,我知道我忘了一些東西!編輯即將到來。 –
再次......感謝您的快速響應和更新。如您所見,我沒有任何'@ XmlSeeAlso'參考,因此,我不知道爲什麼會發生這種情況。 any元素實際上是一個擴展,因此其他人可以自己添加內容。沒有模式,沒有一代,沒有。只是一個擴展點。好的...然後_they_應該只能發送他們真正在xml中使用的名稱空間聲明。沒有從我們這邊清理。 ;-) – Ingo