项目在使用JAXB转换对象到xml文件是总是莫名其妙的生成ns2的前缀,经过查询资料总结出两种方式:不清楚注解作用的转这里:
https://blog.csdn.net/lhzjj/article/details/11796713
(1)pack-info.java方式
在要转换对象目录下新建pack-info.java并进行相关配置即可:以下是demo
package com.cn.rcp.xsdtest;
import java.io.StringWriter;
import java.util.Date;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
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.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.cn.rcp.xsdtest.EnvelopInfo;
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
public class Root {
public static void main(String[] args) {
RootClass rc = new RootClass();
EleClassA a = new EleClassA();
EleClassB b = new EleClassB();
a.setAttrC("attrc");
a.setEleA("eleA");
a.setEleB("eleB");
b.setAttrPassword("attrPassword");
b.setAttrUserName("attrUsrName");
b.setEleCode("eleCode");
rc.setA(a);
rc.setB(b);
rc.setRoot("root");
rc.setRootA("rootA");
JAXBContext context;
try {
context = JAXBContext.newInstance(RootClass.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
//mar.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, value);
//mar.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.w3.orgxxx#");
StringWriter writer = new StringWriter();
mar.marshal(rc, writer);
System.out.println(writer.toString());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="rootcfsdf")
class RootClass {
private EleClassA a;
private EleClassB b;
private String root;
private String rootA;
public EleClassA getA() {
return a;
}
public void setA(EleClassA a) {
this.a = a;
}
public EleClassB getB() {
return b;
}
public void setB(EleClassB b) {
this.b = b;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public String getRootA() {
return rootA;
}
public void setRootA(String rootA) {
this.rootA = rootA;
}
}
@XmlAccessorType(XmlAccessType.PROPERTY)
class EleClassA {
private String eleA;
private String eleB;
private String attrC;
public String getEleA() {
return eleA;
}
public void setEleA(String eleA) {
this.eleA = eleA;
}
@XmlElement(name="elebnewname")
public String getEleB() {
return eleB;
}
public void setEleB(String eleB) {
this.eleB = eleB;
}
//@XmlAttribute()
@XmlTransient
public String getAttrC() {
return attrC;
}
public void setAttrC(String attrC) {
this.attrC = attrC;
}
}
class EleClassB {
private String attrUserName;
private String attrPassword;
private String eleCode;
@XmlAttribute
public String getAttrUserName() {
return attrUserName;
}
public void setAttrUserName(String attrUserName) {
this.attrUserName = attrUserName;
}
@XmlAttribute(name="password")
public String getAttrPassword() {
return attrPassword;
}
public void setAttrPassword(String attrPassword) {
this.attrPassword = attrPassword;
}
public String getEleCode() {
return eleCode;
}
public void setEleCode(String eleCode) {
this.eleCode = eleCode;
}
}
pack-info.java:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.w3.org/2000/09/xmldsig#",
xmlns={@javax.xml.bind.annotation.XmlNs(prefix="xsd",namespaceURI="http://www.sdeport.gov.cn/xsd/ArrivalSchema.xsd"),
@javax.xml.bind.annotation.XmlNs(prefix="",namespaceURI="http://www.w3.org/2000/09/xmldsig#")}
, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.cn.rcp.xsdtest;
结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rootcfsdf xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:xsd="http://www.sdeport.gov.cn/xsd/ArrivalSchema.xsd">
<a>
<eleA>eleA</eleA>
<elebnewname>eleB</elebnewname>
</a>
<b password="attrPassword" attrUserName="attrUsrName">
<eleCode>eleCode</eleCode>
</b>
<root>root</root>
<rootA>rootA</rootA>
</rootcfsdf>
(2)
不用pack-info.java
package com.cn.rcp.xsd;
import java.io.StringWriter;
import java.util.Date;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
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.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.cn.rcp.xsdtest.EnvelopInfo;
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
public class Root {
public static void main(String[] args) {
RootClass rc = new RootClass();
EleClassA a = new EleClassA();
EleClassB b = new EleClassB();
a.setAttrC("attrc");
a.setEleA("eleA");
a.setEleB("eleB");
b.setAttrPassword("attrPassword");
b.setAttrUserName("attrUsrName");
b.setEleCode("eleCode");
rc.setA(a);
rc.setB(b);
rc.setRoot("root");
rc.setRootA("rootA");
JAXBContext context;
try {
context = JAXBContext.newInstance(RootClass.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
//mar.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, value);
//mar.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.w3.orgxxx#");
mar.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
@Override
public String getPreferredPrefix(String namespaceUri,
String suggestion, boolean requirePrefix) {
if (namespaceUri.equals("http://www.w3.org/2000/09/xmldsig#")) {
return "";
}
if (namespaceUri.equals("http://www.w3.org")){
return "org";
}
return suggestion;
}
});
StringWriter writer = new StringWriter();
mar.marshal(rc, writer);
System.out.println(writer.toString());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="rootclass" , namespace="http://www.w3.org/2000/09/xmldsig#")
class RootClass {
@XmlElement(namespace="http://www.w3.org/2000/09/xmldsig#")
private EleClassA a;
@XmlElement(namespace="http://www.w3.org/2000/09/xmldsig#")
private EleClassB b;
@XmlElement(namespace="http://www.w3.org")
private String root;
@XmlElement(namespace="http://www.w3.org/2000/09/xmldsig#")
private String rootA;
public EleClassA getA() {
return a;
}
public void setA(EleClassA a) {
this.a = a;
}
public EleClassB getB() {
return b;
}
public void setB(EleClassB b) {
this.b = b;
}
public String getRoot() {
return root;
}
public void setRoot(String root) {
this.root = root;
}
public String getRootA() {
return rootA;
}
public void setRootA(String rootA) {
this.rootA = rootA;
}
}
@XmlAccessorType(XmlAccessType.PROPERTY)
class EleClassA {
private String eleA;
private String eleB;
private String attrC;
@XmlElement(namespace="http://www.w3.org/2000/09/xmldsig#")
public String getEleA() {
return eleA;
}
public void setEleA(String eleA) {
this.eleA = eleA;
}
@XmlElement(name="elebnewname",namespace="http://www.w3.org/2000/09/xmldsig#")
public String getEleB() {
return eleB;
}
public void setEleB(String eleB) {
this.eleB = eleB;
}
//@XmlAttribute()
@XmlTransient
public String getAttrC() {
return attrC;
}
public void setAttrC(String attrC) {
this.attrC = attrC;
}
}
class EleClassB {
private String attrUserName;
private String attrPassword;
private String eleCode;
@XmlAttribute
public String getAttrUserName() {
return attrUserName;
}
public void setAttrUserName(String attrUserName) {
this.attrUserName = attrUserName;
}
@XmlAttribute(name="password")
public String getAttrPassword() {
return attrPassword;
}
public void setAttrPassword(String attrPassword) {
this.attrPassword = attrPassword;
}
@XmlElement(namespace="http://www.w3.org/2000/09/xmldsig#")
public String getEleCode() {
return eleCode;
}
public void setEleCode(String eleCode) {
this.eleCode = eleCode;
}
}
结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rootclass xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:org="http://www.w3.org">
<a>
<eleA>eleA</eleA>
<elebnewname>eleB</elebnewname>
</a>
<b password="attrPassword" attrUserName="attrUsrName">
<eleCode>eleCode</eleCode>
</b>
<org:root>root</org:root>
<rootA>rootA</rootA>
</rootclass>
总结:
以上两种方式其实都是将所有元素ElEMENT都加上namespace的方法实现的,只是pack-info.java中的namespace = "http://www.w3.org/2000/09/xmldsig#"是将同级包目录下所有的jaxb实体都增加上来namespace,然后用XmlNs的方式设置前缀,而不用pack-info.java的第二种方式其实是手动给所有jaxb实体的ELEMENT上添加了namespace,然后用匿名内部类NamespacePrefixMapper的方式进行前缀设置,两种方式都可以实现表空间前缀的设置,之所以你的代码转换的时候出现ns2是因为ns2所在的那个元素ELEMENT上没有指定namespace,那在转换的时候未定义命名空间的那个ELEMENT就会被认为是默认的命名空间下的元素,所以下面 <a> 节点没有前缀,一个xml只能有一个默认的命名空间,所以再用匿名内部类NamespacePrefixMapper的方式进行前缀设置的时候
if(namespaceUri.equals("http://www.w3.org/2000/09/xmldsig#")) {return "";}
返回的这个“”就和<a>节点冲突了,这种情况下就会默认生成一个前缀就是这个ns2.
也就是说ns2其实是Marshaller 在转换的时候为未定义的ELEMENT自动生成的一个前缀,因为xml文件里面每一个节点都需要有明确的命名空间,也就是定义这个节点的xsd,否则就像类没有所属的jar包一样没有明确的意义。