XmlValidationModeDetector

对于Xml来说有两种约束方式:DTD,XSD(xml schema defenition),在Spring中用来判断以何种解析方式的就是XmlValidationModeDetector类。这其中有一些方法我觉得设计的很巧妙:


    public int detectValidationMode(InputStream inputStream) throws IOException {
        // Peek into the file to look for DOCTYPE.
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            boolean isDtdValidated = false;
            String content;
            while ((content = reader.readLine()) != null) {
                content = consumeCommentTokens(content);
                //如果读取的行是注释或空则略过
                if (this.inComment || !StringUtils.hasText(content)) {
                    continue;
                }
                if (hasDoctype(content)) {  //DOCTYPE = "DOCTYPE"
                    isDtdValidated = true;
                    break;
                }
                if (hasOpeningTag(content)) {
                    // End of meaningful data...
                    break;
                }
            }
            return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
        }
        catch (CharConversionException ex) {
            // Choked on some character encoding...
            // Leave the decision up to the caller.
            return VALIDATION_AUTO;
        }
        finally {
            reader.close();
        }
    }

//START_COMMENT = "<!--"; END_COMMENT = "-->"
    private String consumeCommentTokens(String line) {
        //如果是普通的语句就直接返回
        if (!line.contains(START_COMMENT) && !line.contains(END_COMMENT)) {
            return line;
        }
        String currLine = line;
        while ((currLine = consume(currLine)) != null) {
            if (!this.inComment && !currLine.trim().startsWith(START_COMMENT)) {
                return currLine;
            }
        }
        return null;
    }

    private String consume(String line) {
        int index = (this.inComment ? endComment(line) : startComment(line));
        return (index == -1 ? null : line.substring(index));
    }

    private int startComment(String line) {
        return commentToken(line, START_COMMENT, true);
    }

    private int endComment(String line) {
        return commentToken(line, END_COMMENT, false);
    }

    private int commentToken(String line, String token, boolean inCommentIfPresent) {
        int index = line.indexOf(token);
        if (index > - 1) {
            this.inComment = inCommentIfPresent;
        }
        return (index == -1 ? index : index + token.length());
    }

这些代码完成了这些操作:首先如果是普通的语句就判断是否有"DOCTYPE";如果是注释语句呢?这就是我觉的设计巧妙的地方:
首先,boolean inComment标记用来标记当前状态是否在注释语句内`
int index = (this.inComment ? endComment(line) : startComment(line));
刚开始碰到一个注释语句,会执行startComment(line),inComment变为true,返回一个剔除"<! --"的String,回到consumeCommentTokens方法,while循环继续。

接着会执行endComment(line),如果注释结束则inComment变为false,返回一个空String(即String内部value[]为空,但是!=null),该空会被返回给consumeCommentTokens方法,然后被忽略掉;如果注释没结束,即没检测到
“-->”,inCommen仍为true

转载于:https://my.oschina.net/u/3579120/blog/1532852

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值