2021SC@SDUSC【软件工程应用与实践】Cocoon项目10——xml文件夹分析(2)

2021SC@SDUSC

SAXParser.java

1、总结

解析器可用于解析 InputSource 对象给出的任何 XML 文档。 它可以从解析的文档发送 XML 事件

2、方法

void parse( InputSource in, ContentHandler consumer )
throws SAXException, IOException;
  • 解析 InputSource 并将 SAX 事件发送给使用者。
  • 注意:消费者也可以实现 LexicalHandler。 解析应该解决这个问题。
void parse( InputSource in,ContentHandler contentHandler,LexicalHandler 
lexicalHandler )
    throws SAXException, IOException;
  • 解析 InputSource 并将 SAX 事件发送到内容处理程序和词法处理程序

3、其他

补充:InputSource

  1. XML 实体的单个输入源,此类允许 SAX 应用程序将有关输入源的信息封装在单个对象中,该对象可能包括公共标识符、系统标识符、字节流(可能具有指定的编码)和/或字符流。
  2. SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入。如果有可用的字符流,解析器将直接读取该流,忽略在该流中找到的任何文本编码声明。如果没有字符流,但有字节流,解析器将使用该字节流,使用 InputSource 中指定的编码,否则(如果未指定编码)使用算法自动检测字符编码,例如XML 规范。如果字符流和字节流都不可用,解析器将尝试打开到由系统标识符标识的资源的 URI 连接。
  3. InputSource 对象属于应用程序:SAX 解析器绝不会以任何方式修改它(如有必要,它可能会修改副本)。但是,字节流和字符流的标准处理是将它们作为解析结束清理的一部分关闭,因此应用程序不应在将这些流交给解析器后尝试重新使用它们。

DefaultEntityResolver.java

1、总结

使用目录来解析实体的组件。此实现使用来自 http://xml.apache.org/commons/ 的 XML 实体和 URI 解析器,由 Norman Walsh 发布。

2、主要属性

//默认情况下,我们使用这个类的记录器
private Log logger = LogFactory.getLog(getClass());

3、方法

protected String correctUri(String uri) throws IOException {
//如果它是一个文件,我们必须重新创建 url,否则我们会在 windows 下遇到一些问题,其中一些文件引用以“/DRIVELETTER”开头,而一些只以“DRIVELETTER”开头
        if (uri.startsWith("file:")) {
            final File f = new File(uri.substring(5));
            return f.toURL().toExternalForm();
        }
        return uri;
}
  • 正确的资源uri
  • 补充:toExternalForm()
    构造此 URL 的字符串表示形式。 该字符串是通过为此对象调用流协议处理程序的 toExternalForm() 方法来创建的
public void init()
    throws Exception { 
        // 覆盖由 CatalogManager.properties 设置的调试级别
        if ( this.verbosity != null ) {
            if (this.getLogger().isDebugEnabled()) {
                this.getLogger().debug("Setting Catalog resolver verbosity level to " + this.verbosity);
            }
            this.catalogManager.setVerbosity(this.verbosity.intValue());
        }
        //加载内置目录
        if ( this.catalog == null ) {
            this.getLogger().warn("No default catalog defined.");
        } else {
            this.parseCatalog(this.catalog);
        }
        //加载单个附加本地目录
        if ( this.localCatalog != null ) {
            this.parseCatalog( this.localCatalog );
        }
}
  • 设置配置,加载系统目录并应用可能已使用公共 setter 方法设置的任何参数
public InputSource resolveEntity(String publicId, String systemId)
       //publicId - 被引用的外部实体的公共标识符,如果没有提供,则为 null
       //systemId - 被引用的外部实体的系统标识符
             throws SAXException, IOException
             //SAXException - 任何 SAX 异常,可能包装另一个异常
             //IOException - 特定于 Java 的 IO 异常,可能是为 InputSource 创建新 InputStream 或 Reader 的结果
 {
        InputSource altInputSource = this.catalogResolver.resolveEntity(publicId, systemId);
        if (altInputSource != null) {
            if (this.getLogger().isDebugEnabled()) {
                this.getLogger().debug("Resolved catalog entity: "
                    + publicId + " " + altInputSource.getSystemId());
            }
        }
        return altInputSource;
        //描述新输入源的 InputSource 对象,或者为 null 以请求解析器打开到系统标识符的常规 URI 连接
}
  • 允许应用程序解析外部实体。
  • 解析器将在打开除顶级文档实体之外的任何外部实体(包括外部 DTD 子集、DTD 内引用的外部实体和文档元素内引用的外部实体)之前调用此方法:应用程序可能会请求解析器解析 实体本身,它使用替代 URI,或者它使用完全不同的输入源。
  • 应用程序编写者可以使用此方法将外部系统标识符重定向到安全和/或本地 URI,在目录中查找公共标识符,或从数据库或其他输入源(包括例如对话框)读取实体 .
  • 如果系统标识符是 URL,则 SAX 解析器必须在将其报告给应用程序之前完全解析它。

JaxpDOMParser.java

1、总结

使用符合 JAXP 1.1 的解析器的 dom 解析器
继承自AbstractJaxpParser
实现了DOMParser接口

2、方法

protected DocumentBuilder setupDocumentBuilder()
    throws SAXException {
        if ( this.factory == null ) {
            try {
                //调用initDomBuilderFactory(),初始化 dom builder 工厂
                this.initDomBuilderFactory();
            } catch (Exception e) {
                final String message = "Cannot initialize dom builder factory";
                throw new SAXException( message, e );
            }
        }
        DocumentBuilder docBuilder;
        try {
            //使用当前配置的参数创建 DocumentBuilder 的新实例
            docBuilder = this.factory.newDocumentBuilder();
        } catch( final ParserConfigurationException pce ) {
            final String message = "Could not create DocumentBuilder";
            throw new SAXException( message, pce );
        }
        if( this.resolver != null ) {
        //指定要用于解析要解析的 XML 文档中存在的实体的 EntityResolver。 将此设置为 null 将导致底层实现使用它自己的默认实现和行为
            docBuilder.setEntityResolver( this.resolver );
        }
        return docBuilder;
}
  • 如果需要,创建一个新的 DocumentBuilder

  • 补充:DocumentBuilder
    定义用于从 XML 文档获取 DOM 文档实例的 API。 使用这个类,应用程序程序员可以从 XML 获取文档。
    可以从 DocumentBuilderFactory.newDocumentBuilder() 方法获得此类的实例。 一旦获得此类的实例,就可以从各种输入源解析 XML。 这些输入源是 InputStreams、Files、URL 和 SAX InputSources。

protected synchronized void initDomBuilderFactory()
    throws Exception {
        if ( this.factory == null ) {
            if( "javax.xml.parsers.DocumentBuilderFactory".equals( this.documentBuilderFactoryName ) ) {
                this.factory = DocumentBuilderFactory.newInstance();
            } else {
                final Class factoryClass = loadClass( this.documentBuilderFactoryName );
                this.factory = (DocumentBuilderFactory)factoryClass.newInstance();
            }
            //生成的解析器将提供对 XML 名称空间的支持
            this.factory.setNamespaceAware( true );
            //继承自AbstractJaxpParser中的validate值
            this.factory.setValidating( this.validate );
        }
    }
  • 初始化 dom builder 工厂
  • 使用的方法介绍:
  1. public static DocumentBuilderFactory newInstance()
    获取 DocumentBuilderFactory 的新实例。此静态方法创建一个新的工厂实例。此方法使用以下有序查找过程来确定要加载的 DocumentBuilderFactory 实现类:
    (1)使用 javax.xml.parsers.DocumentBuilderFactory 系统属性。
    (2)使用 JRE 目录中的属性文件“lib/jaxp.properties”。这个配置文件是标准的 java.util.Properties 格式,包含实现类的全限定名,键是上面定义的系统属性。 jaxp.properties 文件只被 JAXP 实现读取一次,然后它的值被缓存以备将来使用。如果第一次尝试读取文件时该文件不存在,则不会再尝试检查它是否存在。 jaxp.properties 中的任何属性在第一次读取后都无法更改其值。
    (3)使用由 java.util.ServiceLoader 类定义的服务提供者加载工具,尝试使用默认加载机制定位和加载服务的实现:服务提供者加载工具将使用当前线程的上下文类加载器尝试加载服务。如果上下文类加载器为空,则将使用系统类加载器。
    (4)否则,返回系统默认实现。
  2. public void setNamespaceAware(boolean awareness)
    指定此代码生成的解析器将提供对 XML 名称空间的支持。 默认情况下, this 的值设置为 false
  3. public void setValidating(boolean validating)
    指定此代码生成的解析器将在解析文档时验证文档。 默认情况下,此值设置为 false。
    请注意,此处的“验证”是指 XML 建议中定义的验证解析器。 换句话说,它本质上只是控制 DTD 验证。
public Document parseDocument( final InputSource input )
    throws SAXException, IOException {
        final DocumentBuilder tmpBuilder = this.setupDocumentBuilder();

        final Document result = tmpBuilder.parse( input );

        return result;
  • 实现DOMParser接口,对Document进行解析
  • 调用的public abstract Document parse(InputSource is) throws SAXException, IOException;
    将给定输入源的内容解析为 XML 文档并返回一个新的 DOM Document 对象。 如果 InputSource 为 null,则抛出 IllegalArgumentException
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值