首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Java进行XML解析(JAXB和Root元素)

使用Java进行XML解析(JAXB和Root元素)
EN

Stack Overflow用户
提问于 2018-06-20 02:32:45
回答 1查看 680关注 0票数 3

我正在用Java为一个简单的XML结构编写一个xml解析器,该结构的结构以

代码语言:javascript
复制
<Document xmlns="some value" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

我能够很好地阅读整个XML结构,除了这一行。我能够使用不带xmlns属性的JAXB解析和读取相应的JAVA POJO。但是,如果我添加它,解析器就会抛出异常。

我试过的,

代码语言:javascript
复制
@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;
}
EN

回答 1

Stack Overflow用户

发布于 2018-06-20 02:42:36

编辑

成功使用以下代码:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@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;
}

假设你有:

代码语言:javascript
复制
<Document xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

删除这些:

代码语言:javascript
复制
@XmlAttribute(name = "xmlns:xsi", required = true)
String xmlnsXsi;
@XmlAttribute(name = "xmlns", required = true)
String xmlns;

您不需要将名称空间映射为属性。

您需要使用命名空间定义根元素:

代码语言:javascript
复制
@XmlRootElement(name = "Document", namespace= "http://test.com")

来进一步解释一下。想象一下,在XML中,您有两种不同类型的用户。一个用户是具有名称、登录名和密码的DB用户,另一个用户具有名称和证书。

你可以创建类似这样的东西:

代码语言:javascript
复制
<user name="">
    <login></login>
    <password></password>
    <cert></cert>
</user>

但是这样的结构并不符合要求。用户定义不同。因此,您可能需要创建两个定义:

代码语言:javascript
复制
<user name="">
    <login></login>
    <password></password>
</user>

<user name="">
    <cert></cert>
</user>

但是如何在同一个XML中区分这两个定义呢?这就是名称空间的用途。它们允许在同一个XML文档中使用具有相同名称但内容不同的标签:

代码语言:javascript
复制
<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,并将它们用作前缀:

代码语言:javascript
复制
<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“名称空间中定义的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50934886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档