使用 castor 解析XML

引包

 
            org.codehaus.castor
            com.springsource.org.exolab.castor.xml
            1.2.0
  

目标 XML文件

target.xml



    

        
            java对象1的描述
            1
        

        
            java对象2的描述
            10
        

    

配置Mapping需要的配置信息

config.xml
config.xml 的作用是:Mapping对象根据config.xml里的映射关系,将target.xml里解析出来的数据,通过反射注入对我们所需的对象。
案列所示,有三个层级关系,分别使用对象Plugin、Extension、Operation来表示



     the Config of the Castor Mapping 

    
        
        
            
        
        
            
        
        
            
        
        
            
        
    

    
        
        
            
        
        
            
        
        
            
        
    

    
        
        
            
        
        
            
        
        
            
        
    


所需对象

Plugin

@Getter
@Setter
public class Plugin implements Serializable {

    private Long id;

    private String name;

    private String version;

    private ArrayList extensions;

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Plugin{");
        sb.append("name='").append(name).append('\'');
        sb.append(", version='").append(version).append('\'');
        sb.append(", extensions=").append(extensions);
        sb.append('}');
        return sb.toString();
    }
}

Extension

@Getter
@Setter
public class Extension {

    private String id;

    private String className;

    private ArrayList operationGroup;

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Extension{");
        sb.append("id='").append(id).append('\'');
        sb.append(", className='").append(className).append('\'');
        sb.append(", operationGroup=").append(operationGroup);
        sb.append('}');
        return sb.toString();
    }
}

Operation

@Getter
@Setter
public class Operation implements Serializable {

    private String name;

    private String desc;

    private Integer index;

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Operation{");
        sb.append("name='").append(name).append('\'');
        sb.append(", desc='").append(desc).append('\'');
        sb.append(", index=").append(index);
        sb.append('}');
        return sb.toString();
    }
}

XMLHelper

解析xml的方法定义在这里


@Slf4j
@Component
public class XMLHelper {

    /**
     * 加载Mapping的配置信息
     *
     * @param mappingPath mapping 文件的地址
     * @return Mapping
     */
    private Mapping loadMapping(String mappingPath) throws CustomException {
        Mapping result;

        if (StringUtil.isEmpty(mappingPath)) {
            throw new CustomException("mappingPath is Empty...");
        }
        result = new Mapping();
        String absolutePath = FileUtil.getFileAbsolutePath(mappingPath, "Mapping配置文件");
        try {
            result.loadMapping(absolutePath);
        } catch (IOException e) {
            log.error("文件不存在");
        } catch (MappingException e) {
            log.error("加载Mapping所需配置信息失败,(可能原因:xml文件中的配置项与java类不合)原因:" + e.getMessage(), e);
            throw new CustomException("加载Mapping所需配置信息失败");
        }

        return result;
    }

    /**
     * 解析xml文件
     *
     * @param xmlPath           xml文件在工程里的相对路径
     * @param mappingConfigPath 解析xml文件,储存Mapping对象需要的配置信息的辛苦xml文件的相对练路径
     * @return Plugin对象
     * @throws CustomException 系统自定义异常
     */
    public Plugin parse(String xmlPath, String mappingConfigPath) throws CustomException {
        if (StringUtil.isEmpty(xmlPath) || StringUtil.isEmpty(mappingConfigPath)) {
            log.error(String.format("解析XML文件时,发现文件地址为空。" +
                    "xmlPath = [%s] , mappingConfigPath = [%s]", xmlPath, mappingConfigPath));
            throw new CustomException("文件地址为空");
        }

        Mapping mapping = this.loadMapping(mappingConfigPath);
        String xmlAbsolutePath = FileUtil.getFileAbsolutePath(xmlPath, "被解析的XML文件");

        String encoding = getDeclaredFileEncoding(xmlAbsolutePath);

        Unmarshaller unmarshaller = new Unmarshaller();
        try {
            unmarshaller.setMapping(mapping);
            return parseByUnmarshaller(unmarshaller, xmlAbsolutePath, encoding);
        } catch (Exception e) {
            log.error("使用Unmarshaller解析XML失败,原因:" + e.getMessage(), e);
            // 解决xml汉字乱码引起的xml解析失败的问题,用UTF-8重新解析一次
            return parseByUnmarshaller(unmarshaller, xmlAbsolutePath, CharSetEnum.UTF8.value);
        }

    }

    private Plugin parseByUnmarshaller(Unmarshaller unmarshaller, String xmlAbsolutePath, String encoding) throws CustomException {
        Plugin result;

        File target = new File(xmlAbsolutePath);

        try (InputStream input = new FileInputStream(target);
             Reader reader = new InputStreamReader(input, encoding)) {

            result = (Plugin) unmarshaller.unmarshal(reader);
        } catch (Exception e) {
            log.error(String.format("解析xml[%s]失败,原因:%s", xmlAbsolutePath, e.getMessage()), e);
            throw new CustomException("解析xml失败");
        }

        return result;
    }

    /**
     * 获取xml文件的编码
     *
     * @param filePath 文件地址
     * @return charSet eg:UTF-8
     */
    private String getDeclaredFileEncoding(String filePath) {
        String encoding = CharSetEnum.GBK.value;

        if (!filePath.endsWith(".xml")) {
            return encoding;
        }

        try (FileReader fileReader = new FileReader(filePath);
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {
            String line = bufferedReader.readLine();

            // 简单判断, 必须写在首行,且不换行
            if (line.startsWith("") && line.toUpperCase().contains(CharSetEnum.UTF8.value)) {
                encoding = CharSetEnum.UTF8.value;
            }

        } catch (IOException e) {
            log.error("获取文件编码失败,原因:" + e.getMessage(), e);
        }
        return encoding;
    }
}

调用XMLHelper的parse方法

@Slf4j
public class LoadXML {

    public static void main(String[] args) throws CustomException {
        XMLHelper xmlHelper = new XMLHelper();

        String xmlPath = "castor/xml/target.xml";
        String mappingConfigPath = "castor/mapping/config.xml";

        Plugin result = xmlHelper.parse(xmlPath, mappingConfigPath);
        log.info(result.toString());
    }
}

输出结果

...LoadXML - Plugin{name='测试Castor解析', version='1.1', extensions=[Extension{id='extension', className='demo.zh.castor.dto.Extension', operationGroup=[Operation{name='java对象1', desc='java对象1的描述', index=1}, Operation{name='java对象2', desc='java对象2的描述', index=10}]}]}

你可能感兴趣的:(使用 castor 解析XML)