扩展XML Schema Validator--MSV

需求:

      1. 对XML中的某些节点和属性进行特殊的检查;

             > 简单的检查: 不依赖XML上下文;

             > 复杂的检查1: 依赖XML中的前序内容(先声明再使用);

             > 复杂的检查2: 依赖XML中的后序内容(先使用再声明);

      2. 友好的错误信息

             > 错误信息支持中文;

             > 至少需要将出错点定位到行号;

      3. 检查整个XML, 最后统一将错误信息收集成一个XML

 

分析:

      1. 简单属性或节点的检查: 需要参与节点和属性的检查过程;

      2. 复杂查检1: 需要在参与节点和属性检查的过程中, 记录相应的上下文信息, 供后面的检查使用;

      3. 复杂检查2 + 错误定位到哪行: 需要在参与节点和属性检查的过程中, 获取当前的位置信息, 并存储下来, 供检查时出错处理;

      4. 错误提示中文: 需要使用中文的properties文件, 需要修改获取message常量使用中文格式.

实现的XML Schema Validator的工具:

      1. MSV: SUN实现的一套工具.

      2. Xerces-2

      最终决定基于MSV进行扩展.

 

MSV的扩展

      1. 根据schema文件创建一个Verifier

            VerifierFactory factory = new com.sun.msv.verifier.jarv.TheFactoryImpl();

            Verifier verifier = factory.newVerifier(CustomErrorReporter.class.getResourceAsStream(SCHEMA));

 

     2. 定制错误处理

  verifier.setErrorHandler(new ReportErrorHandler(){
   public void error(SAXParseException arg0) throws SAXException {
    System.out.println("line: " + arg0.getLineNumber() + "; column: " + arg0.getColumnNumber() + "; message: " + arg0.getMessage());
   }

 

   public void fatalError(SAXParseException arg0) throws SAXException {
    System.out.println("line: " + arg0.getLineNumber() + "; column: " + arg0.getColumnNumber() + "; message: " + arg0.getMessage());
   }
  });

 

       3. 深入检查的各个阶段(通过SAX pipe line来实现)

  // create a SAX parser
  SAXParserFactory parserFactory = SAXParserFactory.newInstance();
  parserFactory.setNamespaceAware(true);
  XMLReader reader = parserFactory.newSAXParser().getXMLReader();

  // then setup the SAX pipe line as follows:
  //
  //  parser ==> interceptor ==> verifier
  //
  // "interceptor" works as a SAX filter.

  Interceptor interceptor = new Interceptor();
  interceptor.setParent(reader);
  interceptor.setContentHandler(verifier.getVerifierHandler());

 

       其中, Interceptor就是我们可以定制特殊处理的点. 它的定义如下:

 private static class Interceptor extends XMLFilterImpl {
  private Locator locator = null;
  
     public void setDocumentLocator (Locator locator)
     {
      this.locator = locator;
      super.setDocumentLocator(locator);
     }  

  public void startElement(String ns, String local, String qname,
    Attributes atts) throws SAXException {
   super.startElement(ns, local, qname, atts);
  }

  public void endElement(String ns, String local, String qname)
    throws SAXException {
   super.endElement(ns, local, qname);
  }

  public void characters(char[] buf, int start, int len)
    throws SAXException {
   super.characters(buf, start, len);
  }
 }
  

     

       4.  检查XML

           interceptor.parse(new InputSource(CustomErrorReporter.class.getResourceAsStream(DATA)));

 

 

       5. 错误提示使用中文

       可以使用Locale.setDefault(Locale.CHINA)来设置默认的Locale

     

      同时在这个类的同一个包中增加Message_zh_CN.properties文件, 这个文件将中文变成unicode. 可以使用jdk下的工具native2ascii来实现.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值