JAVA实现由XSD转xml
本实现基于JDK1.8,请注意,JDK8以下版本才有xjc,高版本被Oracle阉割了
XSD 转 Java bean
首先需要调用xjc 将xsd 生成W3C标准规范的XML java bean,代码中可以直接使用:
Runtime.getRuntime().exec("xjc -p packageName c;/test.xsd")
生成的java bean会在packageName目录下
Java bean 转 xml
- 扫描packageName,获取生成的class文件,获取ObjectFactory,该工厂提供函数生成了所有你从xsd转化的bean,通过反射调用获取Document 根节点对象,直接上代码
public static List<IsoConfigInfoPO> generateBean(List<String> classes) throws Exception {
List<IsoConfigInfoPO> infoPOList = new ArrayList<>();
for (String aClass : classes) {
if (aClass.contains("ObjectFactory")) {
String packageNm = aClass.substring(aClass.indexOf("pacs"), aClass.lastIndexOf(".")).replace("_", ".");
Class cls = Thread.currentThread().getContextClassLoader().loadClass(aClass);
Object factory = cls.getDeclaredConstructor().newInstance();
for (Method method : cls.getDeclaredMethods()) {
if (method.getName().equals("createDocument") && method.getGenericParameterTypes().length == 0) {
Object doc = method.invoke(factory);
//生成Document根节点对象,并深度赋值所有属性以及属性的属性,递归
deepAssign(doc, doc.getClass());
XmlMapper xmlMapper = new XmlMapper();
//使用jaxb解析document对象为xml
JsonNode rootNood = xmlMapper.readTree(createXML(doc.getClass(), doc, packageNm));
Map.Entry<String, JsonNode> root = rootNood.fields().next();
//解析xml,并生成java bean
infoPOList.addAll(deal(root.getValue(), null, null, root.getKey(), 1, packageNm));
}
}
}
}
return infoPOList;
}
因为获取的document为单一对象,所有需要填充属性,并且深度赋值所有可能的属性,将所有的xml节点属性都赋值,一面后续的转换漏掉了节点
/**
* 初始化对象以及对象的属性,并递归属性的属性,直到均初始化完毕
*
* @param obj 顶级对象
* @param cls 顶级对象的class
* @throws Exception
*/
private static void deepAssign(Object obj, Class cls) throws Exception {
for (Field declaredField : cls.getDeclaredFields()) {
Class filedType = declaredField.getType();
boolean isArray = false;
Class c = null;
Object o = null;
for (Method method : cls.getDeclaredMethods()) {
String methodName = method.getName();
Type[] types = method.getGenericParameterTypes();
//set方法
if (types.length == 1) {
//名字类型匹配上
if (types[0].equals(filedType) && methodName.substring(3).equalsIgnoreCase(declaredField.getName())) {
//不是枚举类和抽象类
if (!Modifier.isAbstract(((Class) types[0]).getModifiers()) && !((Class) types[0]).isEnum()) {
//不是包装和基本的
if (Arrays.stream(TYPES).non