首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

告诉解析器在哪里可以找到模式 使用 JAXP 1.2 进行更有用的文档验证(2)实例

告诉解析器在哪里可以找到模式 使用 JAXP 1.2 进行更有用的文档验证(2)实例

SAX 示例演示了如何使用 JAXP 1.2 中的新特性,通过 SAX 解析器来验证文档。要使用 SAX 解析器来验证文档,请执行以下操作:      
  • 创建一个           SAXParserFactory 对象。
  • 将 namespace-aware 和 validating 特性设置为 true。
  • 获取           SAXParser 对象。
  • 设置模式语言和模式源的特性(这是 JAXP 1.2 和模式中新出现的)。
  • 解析文档。解析器必须有权访问           ErrorHandler 对象。
清单 2. ValidateSAX.java 演示了 JAXP 1.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package org.ananas.tips;
import java.io.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
public class ValidateSAX
{
   public static String SCHEMA_LANGUAGE =
      "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                        XML_SCHEMA =
      "http://www.w3.org/2001/XMLSchema",
                        SCHEMA_SOURCE =
      "http://java.sun.com/xml/jaxp/properties/schemaSource";
   public final static void main(String[] args)
      throws IOException, SAXException, ParserConfigurationException
   {
      if(args.length < 2)
      {
         System.err.println("usage is:");
         System.err.println("   java -jar tips.jar -validatesax "
                            + "input.xml schema.xsd");
         return;
      }
      File input = new File(args[0]),
           schema = new File(args[1]);
      SAXParserFactory factory = SAXParserFactory.newInstance();
      factory.setNamespaceAware(true);
      factory.setValidating(true);
      SAXParser parser = factory.newSAXParser();
      try
      {
         parser.setProperty(SCHEMA_LANGUAGE,XML_SCHEMA);
         parser.setProperty(SCHEMA_SOURCE,schema);
      }
      catch(SAXNotRecognizedException x)
      {
         System.err.println("Your SAX parser is not JAXP 1.2 compliant.");
      }
      parser.parse(input,new ErrorPrinter());
   }
}




ErrorHandler 和验证validating 特性告诉解析器向其           ErrorHandler 对象报告验证错误。实际上,这意味着如果您不注册           ErrorHandler ,您就不会看到错误消息。有些程序员期望解析器在无法验证文档时抛出一个异常,但 SAX 解析器并不这么做。        

要测试 ,需要一个符合 JAXP 1.2 的解析器。查看您最喜欢的解析器的文档,或者下载最新版本的 Apache Xerces(我使用 V2.4.0 来准备这篇技巧文章)。如果您的解析器不符合 JAXP 1.2,那么当您试图设置该特性时,它会抛出一个         SAXNotRecognizedException 异常。这提示您应该升级到最新版本的 Xerces。      
仅仅注册了一个         DefaultHandler 对象,该对象只是在控制台上打印验证错误,如清单 3 所示。您的应用程序可以注册更有趣的处理程序,如一个处理文档内容的处理程序。      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package org.ananas.tips;
import java.text.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class ErrorPrinter
   extends DefaultHandler
{
   private MessageFormat message =
      new MessageFormat("({0}: {1}, {2}): {3}");
   private void print(SAXParseException x)
   {
      String msg = message.format(new Object[]
                                  {
                                     x.getSystemId(),
                                     new Integer(x.getLineNumber()),
                                     new Integer(x.getColumnNumber()),
                                     x.getMessage()
                                  });
      System.out.println(msg);
   }
   public void warning(SAXParseException x)
   {
      print(x);
   }
   public void error(SAXParseException x)
   {
      print(x);
   }
   public void fatalError(SAXParseException x)
      throws SAXParseException
   {
      print(x);
      throw x;
   }
}




DOM 会怎样呢?JAXP 1.2 也定义了用于 DOM 解析器的模式支持,如 中所示。这个过程非常类似于 SAX 解析器的过程,唯一的差异在于您是在工厂(factory)对象上设置属性而不是在解析器对象上设置特性。详细的过程是:      
  • 创建一个           DOMBuilderFactory 对象。
  • 将 namespace-aware 和 validating 特性设置为           true 。
  • 设置模式语言和模式源的属性。如果您的解析器不符合 JAXP 1.2,那么它将抛出一个           IllegalArgumentException 异常。
  • 获取           DocumentBuilder 对象(解析器)。
  • 向解析器注册           ErrorHandler 对象。
  • 解析文档。
这个示例仅仅演示了验证。您的应用程序可以用解析树做更多有趣的事情。
清单 4. ValidateDOM.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package org.ananas.tips;
import java.io.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
public class ValidateDOM
{
   public static String SCHEMA_LANGUAGE =
      "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                        XML_SCHEMA =
      "http://www.w3.org/2001/XMLSchema",
                        SCHEMA_SOURCE =
      "http://java.sun.com/xml/jaxp/properties/schemaSource";
   public final static void main(String[] args)
      throws IOException, SAXException, ParserConfigurationException
   {
      if(args.length < 2)
      {
         System.err.println("usage is:");
         System.err.println("   java -jar tips.jar -validatedom "
                            + "input.xml schema.xsd");
         return;
      }
      File input = new File(args[0]),
           schema = new File(args[1]);
      DocumentBuilderFactory factory =
         DocumentBuilderFactory.newInstance();
      factory.setNamespaceAware(true);
      factory.setValidating(true);
      try
      {
         factory.setAttribute(SCHEMA_LANGUAGE,XML_SCHEMA);
         factory.setAttribute(SCHEMA_SOURCE,schema);
      }
      catch(IllegalArgumentException x)
      {
         System.err.println("Your DOM parser is not JAXP 1.2 compliant.");
      }
      DocumentBuilder parser = factory.newDocumentBuilder();
      parser.setErrorHandler(new ErrorPrinter());
      parser.parse(input);
   }
}




开发更健壮的 XML 应用程序在使用 XML 模式实现健壮的验证时,请记住:(几乎是肯定地)当您的应用程序验证文档时,应用程序不应该取决于文档本身的正确性。更具体地说,它不应当靠拥有正确的         xsi:schemaLocation 属性的文档。
返回列表