我有两个 Xml 文件,一个是
<A>
<B>xxx</B>
</A>
另一个是
<A>
<B>
<C>xxx</C>
</B>
</A>
对于B
元素,我ValueObject
用一个String
字段做了一个。另外,我用元素XmlAdapter<Object, ValueObject>
的boolean
属性制作了 a ,并且在解组时可以,所以我可以判断何时尝试从 a 转换,何时尝试从 a 转换。B
setAdapter(BXmlAdapter.class, new BxmlAdaper(boolean))
BxmlAdaper
String
ValueObject
如果元素B
具有xsi:type="prefix:ValueObject"
第一个 xml 和xsi:type="xs:string"
第二个xml 的属性xml
。它运作良好。我可以用一个解组所有这些
ValueObject
。但是没有xsi:type
,我得到了一个org.apache.xerces.dom.ElementNSImpl
in XmlAdapter
marshall 方法的实例。我该如何解决这个案子。
我也有这两个文件的两个模式文件xml
,所以我想也许我可以使用schema
文件来告诉 JAXBB
元素的类型是什么。但似乎 JAXB 只是使用模式文件来检查。我想念什么吗?
这是 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(BXmlAdapter.class)
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = 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;
}
}
包信息
@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
B
BXmlAdapter.java
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;
}
}
}
A1.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>
A2.xml
<?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>
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();
}
}
}
上面的代码可以正常工作,但是如果 xml 文件中没有 xsi:type。这没用。BXmlAdapter 中 unmarshal 方法的参数是 ElementNSImpl 的一个实例......
我的问题是
如何处理 ElementNSImpl 实例
如果xml文件中没有xsi:type,JAXB可以使用一个ValueObject处理不同的xml文件吗
xsi:type 也在模式文件中。JAXB 可以使用模式文件来决定类型吗?似乎 JAXB 只是在验证中使用模式文件。
谢谢