xml使用详解

一、为什么使用XML

  1. 便于不同应用程序之间通信:XML作为一种平台和语言无关的数据格式,能让不同应用程序之间方便地交换信息。

  2. 便于不同平台之间通信:XML是纯文本格式,能够跨平台使用,如Windows、Linux等操作系统。

  3. 便于不同平台之间数据共享:由于XML文件基于文本格式,任何平台都能够读取和解析,保证了数据的共享和互操作性。

二、DOM读取

XML文件内容

当前解析类型 ocr real

代码示例 :

public void handlerResultXml(LinkedList<ReconResult> list, String xmlStr, String flag) {
    try {
        Document document = null;

        // 检查并去掉XML前置BOM标记
        if (xmlStr.startsWith("\uFEFF")) {
            xmlStr = xmlStr.substring(1);
        }

        try {
            document = DocumentHelper.parseText(xmlStr);
        } catch (DocumentException e) {
            System.out.println("XML解析失败");
            return;
        }

        // 根据配置文件中字段顺序进行解析
        int num = 0;  // 用于区分MRZ信息和VIZ信息

        for (String fieldName : fields.split("、")) {
            String xpathExpression = "//*[@Name='" + fieldName + "']";
            Node node = document.selectSingleNode(xpathExpression);
            if (node != null) {
                ReconResult reconResult = parseNode(node, fieldName, num, flag);
                updateReconResultInList(list, reconResult, flag);
                num++;
            }
        }
    } catch (Exception e) {
        System.out.println("解析XML出现未知异常");
    }
}

private ReconResult parseNode(Node node, String fieldName, int num, String flag) {
    ReconResult reconResult = new ReconResult();
    reconResult.setIndex(Integer.parseInt(((DefaultElement) node).attribute("Index").getValue()));
    reconResult.setOcrName(fieldName); // 保存原始识别结果中的名称

    // 对字段进行重命名操作
    reconResult.setName(getFieldName(fieldName, num));

    String content = StringUtils.isEmpty(node.getText()) ? "" : cleanText(node.getText());
    if (flag.equals("ocr")) {
        reconResult.setContent(content);
    } else if (flag.equals("real")) {
        reconResult.setRealContent(content);
    }

    Attribute posNode = ((DefaultElement) node).attribute("Pos");
    if (posNode != null) {
        reconResult.setPosition(posNode.getValue());
    }

    if (reconResult.getIndex() == 10 || reconResult.getIndex() == 11 || reconResult.getIndex() >= 13) {
        reconResult.setEditState(true);
    }

    return reconResult;
}

private String getFieldName(String fieldName, int num) {
    switch (fieldName) {
        case "MRZ1":
        case "MRZ2":
            return fieldName;
        case "OCR MRZ":
            return "MRZ(VIZ)";
        case "出生地点拼音":
            return "出生地点本国(VIZ)";
        case "签发地点拼音":
            return "签发地点本国(VIZ)";
        case "监护人姓名":
            return "母名(VIZ)";
        case "国籍":
            return "本国国籍(VIZ)";
        default:
            return num < 13 ? fieldName.replaceAll("[a-zA-Z]|\\(|\\)", "") + "(MRZ)" :
                    fieldName.replaceAll("[a-zA-Z]|\\(|\\)", "") + "(VIZ)";
    }
}

private String cleanText(String text) {
    return text.replaceAll("\r", "").replaceAll("\n", "").replaceAll("\t", "");
}

private void updateReconResultInList(LinkedList<ReconResult> list, ReconResult reconResult, String flag) {
    ReconResult existingResult = list.stream()
            .filter(o -> o.getName().equals(reconResult.getName()))
            .findAny()
            .orElse(null);

    if (existingResult != null) {
        // 当前集合中已经存在内容,修改对应的值和坐标
        list.forEach(o -> {
            if (o.getName().equals(reconResult.getName())) {
                o.setPosition(reconResult.getPosition());
                if (flag.equals("real")) {
                    o.setRealContent(StringUtils.isEmpty(reconResult.getRealContent()) ? "" : reconResult.getRealContent());
                }
                if (flag.equals("ocr")) {
                    o.setContent(StringUtils.isEmpty(reconResult.getContent()) ? "" : reconResult.getContent());
                }
            }
        });
    } else {
        // 答案不存在的情况下该值为null,进行空值处理,减少前端判断
        if (StringUtils.isEmpty(reconResult.getRealContent())) reconResult.setRealContent("");
        list.add(reconResult);
    }
}

封装示例

public String getXmlByResult(LinkedList<ReconResult> xmlHandelList, String flag) {
    StringBuilder xml = new StringBuilder();
    xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append("\r\n");
    xml.append("<IDCardInfo>").append("\r\n");

    // 将数据集合按照索引排序
    List<ReconResult> sortedList = xmlHandelList.stream()
            .sorted(Comparator.comparingInt(ReconResult::getIndex))
            .collect(Collectors.toList());

    int count = 0;
    for (ReconResult reconResult : sortedList) {
        if (reconResult.getIndex() == -1) continue;

        // 开始创建Field标签
        xml.append("\t").append("<Field Index=\"").append(reconResult.getIndex()).append("\" ");

        // 添加Name和Pos属性
        String fieldName = flag.equals("ocr") ? escapeXml(reconResult.getOcrName()) : escapeXml(getRealName(reconResult));
        xml.append("Name=\"").append(fieldName).append("\" ");

        if (flag.equals("ocr")) {
            xml.append("Pos=\"").append(reconResult.getPosition()).append("\">");
            // 添加内容
            String content = reconResult.getContent();
            xml.append("<![CDATA[").append(content != null ? content : "").append("]]>");
            if (content != null) count++;
        } else {
            xml.append(">");
            // 添加内容
            String realContent = reconResult.getRealContent();
            xml.append(realContent != null ? escapeXml(realContent) : "");
            if (realContent != null) count++;
        }

        xml.append("</Field>").append("\r\n");
    }

    xml.append("</IDCardInfo>");
    return count == 0 ? "" : xml.toString();
}

private String escapeXml(String input) {
    if (input == null) return "";
    return input.replaceAll("\"", "&quot;")
                .replaceAll("&", "&amp;")
                .replaceAll("<", "&lt;")
                .replaceAll(">", "&gt;")
                .replaceAll("'", "&apos;")
                .replaceAll("’", "&apos;");
}

private String getRealName(ReconResult reconResult) {
    String realName = reconResult.getRealName();
    return StringUtils.isEmpty(realName) ? reconResult.getOcrName() : realName;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值