我有两个Xml文件 一个是
<A>
<B>xxx</B>
</A>
另一个是
<A>
<B>
<C>xxx</C>
</B>
</A>
对于B
元素,我创建了一个ValueObject
字段String
。
另外,我为XmlAdapter<Object, ValueObject>
元素创建了一个boolean
属性,
当你解组时我可以B
所以当尝试从setAdapter(BXmlAdapter.class, new BxmlAdaper(boolean))
转换时尝试转换为BxmlAdaper
时,我可以告诉String
。
如果元素ValueObject
具有第一个xml的属性B
和xsi:type="prefix:ValueObject"
为第二个xsi:type="xs:string"
。它运作良好。我可以用一个解组所有这些
xml
。
但是没有ValueObject
,我在xsi:type
unmarshall方法中得到了org.apache.xerces.dom.ElementNSImpl
的实例。
我该如何解决这个案子。
这两个XmlAdapter
文件也有两个模式文件,所以我想也许我可以使用xml
文件
告诉JAXB schema
元素的类型是什么。但似乎JAXB只使用模式文件来检查。
我想念一下吗?
这是samle代码 A类
B
B类
package example.dto;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import example.adapter.BXmlAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {
@XmlJavaTypeAdapter(BXmlAdapter.class)
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
包信息
package example.dto;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="B")
public class B {
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
jaxb.index
@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, namespace = "http://test/test", xmlns = @javax.xml.bind.annotation.XmlNs(prefix = "test", namespaceURI = "http://test/test"))
package example.dto;
BXmlAdapter.java
A
B
A1.xml
package example.adapter;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import example.dto.B;
public class BXmlAdapter extends XmlAdapter<Object, B> {
private final boolean flg;
public BXmlAdapter() {
this.flg = false;
}
public BXmlAdapter(boolean flg) {
this.flg = flg;
}
@Override
public Object marshal(B v) throws Exception {
if (flg) {
return v.getTest();
} else {
return v;
}
}
@Override
public B unmarshal(Object v) throws Exception {
if (flg) {
B b = new B();
b.setTest((String) v);
return b;
} else {
return (B) v;
}
}
}
A2.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
<test:b xsi:type="test:B" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<test:test>xxxx</test:test>
</test:b>
</test:a>
Xml2JavaObject.java
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
<test:b xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">xxxx2</test:b>
</test:a>
上面的代码工作正常, 但是如果在xml文件中没有xsi:type。 这是行不通的。 BXmlAdapter中unmarshal方法的参数是。的实例 ElementNSImpl ....
我的问题是
如何处理ElementNSImpl实例
如果xml文件中没有xsi:type,则JAXB可以使用一个ValueObject处理不同的xml文件
xsi:type也在模式文件中。 JAXB可以使用模式文件来决定类型吗?看来JAXB 只是在验证中使用模式文件。
由于
答案 0 :(得分:0)
我发现使用@XmlMixed和XmlAdapter来解决这个问题有点难看。 这是代码 A级
package example.dto;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import example.adapter.BXmlAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {
@XmlJavaTypeAdapter(value=BXmlAdapter.class)
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
B级
package example.dto;
public class B {
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
类XmlB
package example.dto;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "B")
public class XmlB {
@XmlMixed
private List<Object> tempElement;
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
public List<Object> getTempElement() {
return tempElement;
}
public void setTempElement(List<Object> tempElement) {
this.tempElement = tempElement;
}
}
package-info.java
@javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, namespace = "http://test/test", xmlns = @javax.xml.bind.annotation.XmlNs(prefix = "test", namespaceURI = "http://test/test"))
package example.dto;
jaxb.index
A
XmlB
A1.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
<test:b>
<test:test>xxxx</test:test>
</test:b>
</test:a>
A2.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test:a xmlns:test="http://test/test">
<test:b>xxxx2</test:b>
</test:a>
BXmlAdapter.java
package example.adapter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import example.dto.B;
import example.dto.XmlB;
public class BXmlAdapter extends XmlAdapter<XmlB, B> {
private final boolean flg;
public BXmlAdapter() {
this.flg = false;
}
public BXmlAdapter(boolean flg) {
this.flg = flg;
}
@Override
public XmlB marshal(B v) throws Exception {
XmlB xmlb = new XmlB();
if (flg) {
List<Object> tempElement = new ArrayList<>();
tempElement.add(v.getTest());
xmlb.setTempElement(tempElement);
} else {
xmlb.setTest(v.getTest());
}
return xmlb;
}
@Override
public B unmarshal(XmlB v) throws Exception {
B b = new B();
if (flg) {
if (v.getTempElement() != null && v.getTempElement().size() == 1) {
b.setTest((String) v.getTempElement().get(0));
}
} else {
b.setTest(v.getTest());
}
return b;
}
}
JavaObject2Xml.java
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import example.adapter.BXmlAdapter;
import example.dto.A;
import example.dto.B;
public class JavaObject2Xml {
public static void main(String[] args) throws ClassNotFoundException {
A a1 = new A();
A a2 = new A();
B b1 = new B();
B b2 = new B();
b1.setTest("xxxx");
b2.setTest("xxxx2");
a1.setB(b1);
a2.setB(b2);
try {
File fileA1 = new File("D:\\jaxb\\A1.xml");
JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(false));
jaxbMarshaller.marshal(a1, fileA1);
} catch (JAXBException e) {
e.printStackTrace();
}
try {
File fileA2 = new File("D:\\jaxb\\A2.xml");
JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(true));
jaxbMarshaller.marshal(a2, fileA2);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Xml2JavaObject.java
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.xml.sax.SAXException;
import example.adapter.BXmlAdapter;
import example.dto.A;
public class Xml2JavaObject {
public static void main(String[] args) throws ClassNotFoundException,
SAXException {
try {
File file = new File("D:\\jaxb\\A1.xml");
JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.setAdapter(BXmlAdapter.class, new BXmlAdapter(false));
A a = (A) jaxbUnmarshaller.unmarshal(file);
System.out.println(a.getB().getTest());
} catch (JAXBException e) {
e.printStackTrace();
}
try {
File file = new File("D:\\jaxb\\A2.xml");
JAXBContext jaxbContext = JAXBContext.newInstance("example.dto");
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.setAdapter(BXmlAdapter.class,new BXmlAdapter(true));
A a = (A) jaxbUnmarshaller.unmarshal(file);
System.out.println(a.getB().getTest());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
上面的代码可以帮助我使用一组Classes来处理2个或更多xml文件