unexpected element (uri:"", local:"sean:person"). Expected elements are <{http://sean.com}person>

JAXB命名空间问题
本文介绍了一个关于Java架构XML绑定(JAXB)处理命名空间时出现的问题。问题发生在尝试将带有特定命名空间的XML文件转换为Java对象时。具体错误信息显示,期望的命名空间与实际读取到的命名空间不匹配。

详细报错如下:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"sean:person"). Expected elements are <{http://sean.com}person>
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1048)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
	at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229)
	at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112)
	at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:95)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:312)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:292)
	at com.sean.JAXBHelper.getObjFromDoc(JAXBHelper.java:22)
	at com.sean.Test.main(Test.java:19)

期待的元素为person,其相应的命名空间为http://sean.com

获取到的元素为person,其相应的命名空间为空

XML Schema文件:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
		targetNamespace="http://sean.com"
		elementFormDefault="qualified" 
		attributeFormDefault="unqualified">
	<xs:element name="person">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="name" type="xs:string"/>
				<xs:element name="age" type="xs:unsignedShort"/>
			</xs:sequence>
			<xs:attribute name="id" type="xs:string"/>
		</xs:complexType>
	</xs:element>
</xs:schema>

通过Eclipse的JAXB插件,使用XML Schema生成的代码:

代码中一定要包含XmlRootElement标签才能使用JAXB进行正转、反转

package com.sean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "name",
    "age"
})
@XmlRootElement(name = "person")
public class Person {

    @XmlElement(required = true)
    protected String name;
    @XmlSchemaType(name = "unsignedShort")
    protected int age;
    @XmlAttribute(name = "id")
    protected String id;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int value) {
        this.age = value;
    }

    public String getId() {
        return id;
    }

    public void setId(String value) {
        this.id = value;
    }
}

进行测试的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<sean:person xmlns:sean="http://sean.com" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<sean:name>abc</sean:name>
	<sean:age>11</sean:age>
</sean:person>

测试方法类:

问题的原因是下面代码中被注释掉的那一行

解析XML文件并构建其对应的Document对象时,默认忽略元素对应的命令空间,JAXB在进行反转时,无法从Document对象中找到元素对应的命令空间,就会包标题的错

package com.sean;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

public class Test {
	public static void main(String[] args) throws Exception {
		String path = Test.class.getResource("/person.xml").getFile();
		File file = new File(path);
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
//	    factory.setNamespaceAware(true);
	    DocumentBuilder builder = factory.newDocumentBuilder();
	    Document doc = builder.parse(file);
		
	    Object obj = JAXBHelper.getObjFromDoc(doc, Person.class);
	    System.out.println(obj.toString());
	}
}
[INFO] Downloading from : http://10.250.127.11:13620/org/apache/maven/plugins/maven-install-plugin/2.5.2/maven-install-plugin-2.5.2.pom [INFO] Downloading from : http://10.250.127.11:13620/org/apache/maven/plugins/maven-plugins/25/maven-plugins-25.pom这个地址能正常下载文件<?xml version='1.0' encoding='UTF-8'?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.maven</groupId> <artifactId>maven-parent</artifactId> <version>24</version> <relativePath>../../pom/maven/pom.xml</relativePath> </parent> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugins</artifactId> <version>25</version> <packaging>pom</packaging> <name>Apache Maven Plugins</name> <description>Maven Plugins</description> <url>http://maven.apache.org/plugins/</url> <scm> <connection>scm:svn:http://svn.apache.org/repos/asf/maven/plugins/tags/maven-plugins-25</connection> <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/plugins/tags/maven-plugins-25</developerConnection> <url>http://svn.apache.org/viewvc/maven/plugins/tags/maven-plugins-25</url> </scm> <ciManagement> <system>Jenkins</system> <url>https://builds.apache.org/job/maven-plugins/</url> </ciManagement> <distributionManagement> <site><!-- to be copied in every plugin pom, since inheritance adds unwanted artifactId --> <id>apache.website</id> <url>scm:svn:https://svn.apache.org/repos/infra/websites/production/maven/content/${maven.site.path}</url> </site> </distributionManagement> <properties> <maven.site.path>plugins-archives/${project.artifactId}-LATEST</maven.site.path> </properties> <repositories> <repository> <id>apache.snapshots</id> <name>Apache Snapshot Repository</name> <url>http://repository.apache.org/snapshots</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-changes-plugin</artifactId> <version>2.9</version> <configuration> <issueManagementSystems> <issueManagementSystem>JIRA</issueManagementSystem> </issueManagementSystems> <maxEntries>1000</maxEntries> <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot> <!-- Used by announcement-generate goal --> <templateDirectory>org/apache/maven/plugins</templateDirectory> <!-- Used by announcement-mail goal --> <subject>[ANN] ${project.name} ${project.version} Released</subject> <toAddresses> <toAddress implementation="java.lang.String">announce@maven.apache.org</toAddress> <toAddress implementation="java.lang.String">users@maven.apache.org</toAddress> </toAddresses> <ccAddresses> <ccAddress implementation="java.lang.String">dev@maven.apache.org</ccAddress> </ccAddresses> <!-- These values need to be specified as properties in the profile apache-release in your settings.xml --> <fromDeveloperId>${apache.availid}</fromDeveloperId> <smtpHost>${smtp.host}</smtpHost> </configuration> <dependencies> <!-- Used by announcement-generate goal --> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-resources</artifactId> <version>1</version> </dependency> </dependencies> </plugin> <plugin> <artifactId>maven-release-plugin</artifactId> <configuration> <tagBase>https://svn.apache.org/repos/asf/maven/plugins/tags</tagBase> <releaseProfiles>apache-release,rat,run-its</releaseProfiles> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-scm-publish-plugin</artifactId> <configuration> <content>${project.reporting.outputDirectory}</content><!-- plugins are mono-module, no real need for site:stage --> </configuration> </plugin> <plugin> <artifactId>maven-enforcer-plugin</artifactId> <executions> <execution> <goals> <goal>enforce</goal> </goals> <id>ensure-no-container-api</id> <configuration> <rules> <bannedDependencies> <excludes> <exclude>org.codehaus.plexus:plexus-component-api</exclude> </excludes> <message>The new containers are not supported. You probably added a dependency that is missing the exclusions.</message> </bannedDependencies> </rules> <fail>true</fail> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <executions> <execution> <id>generated-helpmojo</id> <goals> <goal>helpmojo</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.2</version> </plugin> </plugins> </reporting> <profiles> <profile> <id>quality-checks</id> <activation> <property> <name>quality-checks</name> <value>true</value> </property> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-docck-plugin</artifactId> <executions> <execution> <id>docck-check</id> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>run-its</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-invoker-plugin</artifactId> <configuration> <debug>true</debug> <projectsDirectory>src/it</projectsDirectory> <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> <preBuildHookScript>setup</preBuildHookScript> <postBuildHookScript>verify</postBuildHookScript> <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath> <settingsFile>src/it/settings.xml</settingsFile> <pomIncludes> <pomInclude>*/pom.xml</pomInclude> </pomIncludes> </configuration> <executions> <execution> <id>integration-test</id> <goals> <goal>install</goal> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>reporting</id> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-invoker-plugin</artifactId> <version>1.8</version> </plugin> </plugins> </reporting> </profile> <profile> <id>maven-3</id> <activation> <file> <!-- This employs that the basedir expression is only recognized by Maven 3.x (see MNG-2363) --> <exists>${basedir}</exists> </file> </activation> <build> <plugins> <!-- if releasing current pom with Maven 3, site descriptor must be attached --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <inherited>false</inherited> <executions> <execution> <id>attach-descriptor</id> <goals> <goal>attach-descriptor</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
最新发布
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值