验证同一个XML文件,使用同一个Schema文件,DOM方式与SAX方式结果却不一样。
xml文件内容:
<?xml version="1.0" encoding="gb2312"?>
<action-config xmlns="my:schema">
</action-config>Schema文件内容:
<?xml version="1.0" encoding="GBK" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tholoz="my:schema"
            targetNamespace="my:schema" elementFormDefault="qualified">
  <xsd:element name="action-config">
    <xsd:complexType>
      <xsd:attribute name="default-method" use="required"/>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>根据schema,这个xml文件的内容应该是不合法的。
使用DOM的方式解析:
SchemaFactory sf 
        = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(schemaFile);DocumentBuilderFactory dbf 
        = DocumentBuilderFactory.newInstance();
dbf.setIgnoringComments(true);
dbf.setNamespaceAware(true);
dbf.setSchema(schema);DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(xmlFile));
运行这段代码,抛出了XML不合法的异常,应该是这样的。使用SAX方式验证:
SchemaFactory sf 
        = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(schemaFile);SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
spf.setSchema(schema);
SAXParser sp = spf.newSAXParser();
sp.parse(new File(xmlFile), handler);
运行这段代码,没有像预期的一样抛出异常。从思路上说,在SAXParserFactory对象上设置了schema对象,也应该根据该schema对象来验证XML文件啊,但为什么没有呢?
如果使用SAXParserFactory.setSchema设置了schema对象,但没有验证,那要这个方法来干嘛使?难道这是一个bug?
或者说我的用法不对?
请高人指点。

解决方案 »

  1.   

    顶一下 
    使用 SAXParser 另外一种方式去设置schema的话是应该是可以检验出来的
      

  2.   

    方法一:使用schema验证xml文档
    Source  source = new StreamSource(new File("c:/sample.xml")); 
    schema.newValidator().validate(source);
    代码如上,用schema对象创建一个Validator(我就叫他验证器吧!),然后使用这个验证器去校验你的xml文件.方法二:在parser xml文档的过程中作验证
    parser.parse(new File("c:/sample.xml"), new DefaultHandler() {
    @Override
    public void error(SAXParseException e) throws SAXException {
    e.printStackTrace();
    }
    }); 
    代码如上,在parser的过程中,DefaultHandler中的error这个方法会捕获异常.在这个方法中加上e.printStackTrace();貌似回答的晚了一些,我刚刚看到.