我正在用Java为一个简单的XML结构编写一个xml解析器,该结构的结构以
<Document xmlns="some value" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
我能够很好地阅读整个XML结构,除了这一行。我能够使用不带xmlns属性的JAXB解析和读取相应的JAVA POJO。但是,如果我添加它,解析器就会抛出异常。
我试过的,
@XmlRootElement(name = "Document")
static class UserMetaData {
@XmlAttribute(name = "xmlns:xsi", required = true)
String xmlnsXsi;
@XmlAttribute(name = "xmlns", required = true)
String xmlns;
@XmlElement(name = "User", required = true, nillable = false)
User userRecord;
}
发布于 2018-06-20 02:42:36
编辑
成功使用以下代码:
@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);
}
和bean:
@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中,您有两种不同类型的用户。一个用户是具有名称、登录名和密码的DB用户,另一个用户具有名称和证书。
你可以创建类似这样的东西:
<user name="">
<login></login>
<password></password>
<cert></cert>
</user>
但是这样的结构并不符合要求。用户定义不同。因此,您可能需要创建两个定义:
<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名称空间中定义。它们不再冲突,并被视为具有不同定义的两个不同名称。
但是,为每个标记提到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“将xmlns=根元素的默认名称空间重新定义为"something”。
当JAXB试图解组对象时,它在XML中查找空名称空间中的文档,但找不到它,因为文档是在"something“名称空间中定义的。
https://stackoverflow.com/questions/50934886
复制相似问题