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

2021SC@SDUSC

JaxpSAXParser

1、总结

使用符合 JAXP 1.1 的解析器的 SAX 解析器
继承自AbstractJaxpParser

2、主要属性

//SAX 解析器工厂
protected SAXParserFactory factory;
//是否需要将命名空间也作为属性的判断标志,默认为假
protected boolean nsPrefixes = false;
//是否需要停止警告的判断标志,默认为真
protected boolean stopOnWarning = true;
//是否需要停止可恢复的错误的判断标志,默认为真
protected boolean stopOnRecoverableError = true;
//是否应该删除 start/endDTD 事件之间出现的comment事件,默认为假
protected boolean dropDtdComments = false;
//sax 解析器工厂的名称
protected String saxParserFactoryName = "javax.xml.parsers.SAXParserFactory";

3、方法

public void setDropDtdComments(boolean dropDtdComments) {
        this.dropDtdComments = dropDtdComments;
}
  • 是否应该删除来自 DTD 的 comment() 事件?(默认为false)
  • 因为无论如何这个实现都不支持DeclHandler 接口,所以只有来自DTD 的注释是没有用的。来自内部DTD 子集的注释事件将再次出现在序列化输出中。
public void setNsPrefixes(boolean nsPrefixes) {
        this.nsPrefixes = nsPrefixes;
}
  • 我们是否希望命名空间声明也作为 ‘xmlns:’ 属性? 默认为假。
  • 注意:将此设置为 true 会混淆某些 XSL 处理器(例如 Saxon)
public void setSaxParserFactoryName(String saxParserFactoryName) {
        this.saxParserFactoryName = saxParserFactoryName;
}
  • 设置要使用的 SAXParserFactory 实现类的名称,而不是使用标准的 JAXP 机制 (SAXParserFactory.newInstance())
  • 这允许当其中几个在类路径中可用时,明确选择要使用的 JAXP 实现
public void fatalError( final SAXParseException spe )
throws SAXException
  • 接收致命错误时进行通知
public void setStopOnRecoverableError(boolean stopOnRecoverableError)
  • 如果发生可恢复的错误,判断解析器是否应该停止解析, 默认为真
public void parse( final InputSource in,
                       final ContentHandler contentHandler,
                       final LexicalHandler lexicalHandler )
    throws SAXException, IOException {
        final XMLReader tmpReader = this.setupXMLReader();

        try {
            LexicalHandler theLexicalHandler = null;
            if ( null == lexicalHandler 
                 && contentHandler instanceof LexicalHandler) {
                theLexicalHandler = (LexicalHandler)contentHandler;
            }   
            if( null != lexicalHandler ) {
                theLexicalHandler = lexicalHandler;
            }
            if (theLexicalHandler != null) {
                if (this.dropDtdComments) {
                    theLexicalHandler = new DtdCommentEater(theLexicalHandler);
                }
                tmpReader.setProperty( "http://xml.org/sax/properties/lexical-handler",
                                       theLexicalHandler );
            }
        } catch( final SAXException e ) {
            final String message =
                "SAX2 driver does not support property: " +
                "'http://xml.org/sax/properties/lexical-handler'";
            this.getLogger().warn( message );
        }
        tmpReader.setContentHandler( contentHandler );

        tmpReader.parse( in );
    }
  1. 补充:ContentHandler

接收文档逻辑内容的通知
这是大多数 SAX 应用程序实现的主要接口:如果应用程序需要获知基本解析事件,则它实现此接口并使用 setContentHandler() 向 SAX 解析器注册一个实例。解析器使用实例报告基本的文档相关事件,如元素和字符数据的开始和结束
此界面中的事件顺序非常重要,它反映了文档本身的信息顺序。例如,元素的所有内容(字符数据、处理指令和/或子元素)将按顺序出现在 startElement 事件和相应的 endElement 事件之间

public void setContentHandler (ContentHandler handler);
  • 允许应用程序注册内容事件处理程序,如果应用程序未注册内容处理程序,则 SAX 解析器报告的所有内容事件都将被静默忽略。
  • 应用程序可能会在解析过程中注册一个新的或不同的处理程序,并且 SAX 解析器必须立即开始使用新的处理程序。
  1. 补充:LexicalHandler

这是 SAX2 的可选扩展处理程序,用于提供有关 XML 文档的词法信息,例如注释和 CDATA 节边界。 XML 阅读器不需要识别此处理程序,并且它不是仅核心 SAX2 发行版的一部分。
词法处理程序中的事件适用于整个文档,而不仅仅是文档元素,并且所有词法处理程序事件都必须出现在内容处理程序的 startDocument 和 endDocument 事件之间。

4、嵌套类

JaxpSAXParser.DtdCommentEater:

一个 LexicalHandler 实现,它去除了 startDTD 和 endDTD 之间的所有评论事件。 在所有其他情况下,事件被转发到另一个 LexicalHandler

protected static class DtdCommentEater implements LexicalHandler {
        protected LexicalHandler next;
        protected boolean inDTD;
        public DtdCommentEater(LexicalHandler nextHandler) {
            this.next = nextHandler;
        }
        public void startDTD (String name, String publicId, String systemId)
        throws SAXException {
            inDTD = true;
            next.startDTD(name, publicId, systemId);
        }
        public void endDTD ()
        throws SAXException {
            inDTD = false;
            next.endDTD();
        }
        public void startEntity (String name)
        throws SAXException {
            next.startEntity(name);
        }
        public void endEntity (String name)
        throws SAXException {
            next.endEntity(name);
        }
        public void startCDATA ()
        throws SAXException {
            next.startCDATA();
        }
        public void endCDATA ()
        throws SAXException {
            next.endCDATA();
        }
        public void comment (char ch[], int start, int length)
        throws SAXException {
            if (!inDTD) {
                next.comment(ch, start, length);
            }
        }
    }

包含的方法:

public void startDTD (String name, String publicId, String systemId)
        throws SAXException
  • 报告 DTD 声明的开始(如果存在),此方法主要用于报告 DOCTYPE 声明的开始;如果文档没有任何 DOCTYPE 声明,则不调用此方法

  • 通过 DTDHandler 或 DeclHandler 事件报告的所有声明必须在 startDTD 和 endDTD 事件之间出现。可以假设声明属于内部 DTD 子集,除非它们在 startEntity 和 endEntity 事件之间出现。也应该在 startDTD 和 endDTD 事件之间,以事件出现的原始顺序(逻辑)报告 DTD 的注释和处理指令;但是,它们不需要出现在相对于 DTDHandler 或 DeclHandler 事件的正确位置

  • 注意,start/endDTD 事件将出现在 ContentHandler 的 start/endDocument 事件中,并在第一个 startElement 事件之前

  • 参数:
    name —— 文档类型名称。
    publicId —— 用于外部 DTD 子集的已声明的公共标识符,如果没有声明,则为 null。
    systemId —— 用于外部 DTD 子集的已声明的系统公共标识符,如果没有声明,则为 null。(注意,这不能根据文档基 URI 解析)

 public void endDTD ()
        throws SAXException 
  • 报告 DTD 声明的结束,此方法主要用于报告 DOCTYPE 声明的结束;如果文档没有任何 DOCTYPE 声明,则不调用此方法
 public void startEntity (String name)
        throws SAXException
  • 报告一些内部和外部 XML 实体的开始,参数实体(包括外部 DTD 子集)的报告是可选的,报告 LexicalHandler 事件的 SAX2 驱动程序不能实现它;可以使用 http://xml.org/sax/features/lexical-handler/parameter-entities 功能查询或控制参数实体的报告

  • 使用其正规名称报告常规实体,参数实体具有置于其名称前的 “%”,并且外部 DTD 子集具有伪实体名 “[dtd]”

  • 在 SAX2 驱动程序提供这些事件时,所有其他事件必须在开始/结束实体事件中正确嵌套。不存在对来自 DeclHandler()DTDHandler() 的事件进行正确排序的 附加要求

  • 注意,跳过的实体将通过 skippedEntity() (是 ContentHandler 接口的一部分)报告

  • 参数:
    name —— 实体的名称。如果是参数实体,则名称将以 “%” 开头,如果是外部 DTD 子集,则将是 “[dtd]”

public void startCDATA ()
        throws SAXException
  • 报告 CDATA 节的开始,通过常规 characters 事件报告 CDATA 节的内容;此事件仅用于报告边界
public void comment (char ch[], int start, int length)
        throws SAXException
  • 报告文档的任何位置的 XML 注释,此回调将用于文档元素内外的注释,包括外部 DTD 子集中的注释(如果读取)。必须在 start/endDTDstart/endEntity 事件内部正确嵌套 DTD 中的注释(如果已使用)
    -参数:
    ch —— 保存注释中的字符的数组。
    start —— 数组中的开始位置。
    length —— 使用的数组中的字符数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值