最近有个需求是根据文档,来进行不同申请类型不同项目类型来进行相关xml文档的校验(校验规则就是文档里的属性类型,长度等),因此了解到了SAXReader和XSD两种解析xml的方法,一开始公司打算使用SAXReader取出相关值,直接进行判断。后来发现这个方法拓展性不是很好,就改为了xsd。
由于需要根据不同申请和项目类型进行不同的内容验证,所以首先需要读取xml文件的内容
示例xml文件
<APP>
<HEADER>
xxx
</HEADER>
<!--数据区-->
<DATA>
<IN_ITEM_TYPE>40</IN_ITEM_TYPE>
xxxxxxx
</DATA>
</APP>
直接上代码
SAXReader reader = new SAXReader();
// 通过xml文件路径实例化file对象生成文档对象Document
Document document = reader.read(new File(xmlFileUrl));
// 获取xml文档的根节点,也就是<APP></APP>
Element node = document.getRootElement();
// 获取APP下的参数
Element header = node.element("HEADER");
Element data = node.element("DATA");
// 以此类推获取需要的参数
Element item_type = data.element("IN_ITEM_TYPE");
String itemType = item_type.getText();
这个用法需要几点准备
xsd文件生成方法有两种
首先cd到它某个版本的bin目录下,如
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
执行
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>xsd.exe xxx.xml
就会生成对应的xsd文件,再进行自定义修改
生成了xsd文件,我们就需要根据各自的需求进行个性化的验证,其中,主要有string,int(integer), date, long,double等主要类型
下面分别进行简单介绍,依旧是找到我们需要验证的属性的上级节点,我这里是DATA
其中
<xs:element name="DATA">
<xs:complexType>
<xs:sequence>
<!-- minOccurs="0" 标识不控制不为空,可以不写,但有时候不写会报错-->
<xs:element name="test0" type="xs:string" minOccurs="0" />
<!-- 通过xs:minLength 为1 和 xs:maxLength 指定上限来控制非空和取值范围-->
<xs:element name="test1" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"></xs:minLength>
<xs:maxLength value="12"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
</xs:element>
<!-- int/integer 可直接通过minOccurs 控制是否非空,也可通过<xs:enumeration value="1"/> 来进行有效值的指定 -->
<xs:element name="test2" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:int">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- 也可通过<xs:enumeration value="1"/> 来进行有效值的指定 -->
<xs:element name="test3" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:int">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
<xs:enumeration value="4"/>
<xs:enumeration value="5"/>
<xs:enumeration value="6"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- double, long,date简单一些,可直接套用下发,改下类型就可以了 -->
<xs:element name="test4" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:double">
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="test5" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:long">
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="test6" minOccurs="1" >
<xs:simpleType>
<xs:restriction base="xs:date">
</xs:restriction>
</xs:simpleType>
</xs:element>
这个方法,如果校验失败会打印校验信息
/**
* xml文件校验器
* @param fileUrl 需要校验的文件地址(本机)
* @param xsdUrl 对应xml的xsd(XML结构定义, XML Schemas Definition)文件
* @return
*/
private ResponseEntity<Result<String>> xmlVaildatorByXsd(String fileUrl, String xsdUrl){
try {
final String sl = XMLConstants.W3C_XML_SCHEMA_NS_URI;
SchemaFactory schemaFactory = SchemaFactory.newInstance(sl);
File schemaLocation = ResourceUtils.getFile(xsdUrl);
Schema schema = schemaFactory.newSchema(schemaLocation);
Source xmlSource = new StreamSource(new File(fileUrl));
Validator validator = schema.newValidator();
validator.validate(xmlSource);
} catch (Exception e) {
log.error("错误信息:" + e.getMessage());
// e.printStackTrace();
System.out.println("错误信息:" + e.getMessage());
return ResponseEntityResult.error(e.getMessage());
}
return ResponseEntityResult.success();
}