编辑
成功使用以下代码:
@Test
public void unmarshal() throws JAXBException {
JAXBContext context = JAXBContext.newInstance(UserData.class);
Unmarshaller unmarshaler = context.createUnmarshaller();
StringReader reader = new StringReader("<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:pain.002.001.03\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><User/></Document>");
UserData result = (UserData) unmarshaler.unmarshal(reader);
System.out.println(result.userRecord);
}
还有豆子:
@XmlRootElement(name = "Document", namespace="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03")
public class UserData {
@XmlElement(name = "User", required = true, nillable = false)
public User userRecord;
}
假设你有:
<Document xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
删除这些:
@XmlAttribute(name = "xmlns:xsi", required = true)
String xmlnsXsi;
@XmlAttribute(name = "xmlns", required = true)
String xmlns;
您不需要将命名空间映射为属性。
您需要使用命名空间定义根元素:
@XmlRootElement(name = "Document", namespace= "http://test.com")
进一步解释一下。想象一下,在 XML 中,您有 2 种不同类型的用户。一个用户是具有名称、登录名和密码的 DB 用户,另一个用户具有名称和证书。
您可以创建如下内容:
<user name="">
<login></login>
<password></password>
<cert></cert>
</user>
但这样的结构不符合要求。用户定义不同。因此,您可能想要创建 2 个定义:
<user name="">
<login></login>
<password></password>
</user>
<user name="">
<cert></cert>
</user>
但是如何区分同一个 XML 中的这两个定义呢?这就是命名空间的目的。它们允许在同一个 XML 文档中使用名称相同但内容不同的标签:
<Document>
<user name="" xmlns="http://user1.com">
<login></login>
<password></password>
</user>
<user name="" xmlns="http://user2.com">
<cert></cert>
</user>
</Document>
第一个用户标签定义在http://user1.com命名空间中,第二个用户标签定义在http://user2.com命名空间中。它们不再冲突,并被视为具有不同定义的 2 个不同名称。
但是,为每个标签提及 xmlns="http://user1.com" 或 xmlns="http://user2.com" 很乏味。命名空间别名在这里很有帮助。您可以在根元素中定义任何命名空间别名,并将别名用作标签前缀。对于我们的示例,我们将定义 2 个别名 user1 和 user2 并将它们用作前缀:
<Document xmlns:user1="http://user1.com" xmlns:user2=xmlns="http://user2.com">
<user1:user name="">
<login></login>
<password></password>
</user>
<user2:user name="">
<cert></cert>
</user>
</Document>
这种方式的 XML 定义更短更清晰。
但请记住,别名只是帮手。XML 解析器和验证器总是用完整的命名空间替换别名,例如http://user1.com " 或http://user2.com用于标签比较。
在您的示例中,添加 xmlns="something" 将 XML 默认命名空间的根元素的默认命名空间重新定义为“something”。
当 JAXB 尝试解组您的对象时,它在 XML 中查找空名称空间中的 Document 并且找不到它,因为 Document 是在“something”名称空间中定义的。