传奇手游开服表网站,wordpress被墙,大连建设工程信息网档案下载,沈阳网站制作优化推广1 XML解析器对比
1. DOM解析器#xff1a;
○ 优点#xff1a;易于使用#xff0c;提供完整的文档树#xff0c;可以方便地修改和遍历XML文档。 ○ 缺点#xff1a;对大型文档消耗内存较多#xff0c;加载整个文档可能会变慢。 ○ 适用场景#xff1a;适合小型XML文档…1 XML解析器对比
1. DOM解析器
○ 优点易于使用提供完整的文档树可以方便地修改和遍历XML文档。 ○ 缺点对大型文档消耗内存较多加载整个文档可能会变慢。 ○ 适用场景适合小型XML文档或需要多次访问和修改XML内容的情况。
2. SAX解析器
○ 优点逐个处理XML元素节省内存适用于一次性遍历大型XML文档。 ○ 缺点编写处理事件的代码可能会相对复杂不适合需要频繁修改XML内容的情况。 ○ 适用场景适合大型XML文档的读取、分析和提取数据。
3. StAX解析器
○ 优点结合了DOM和SAX的优点提供了灵活的编程模型适用于流式处理和部分内存加载。 ○ 缺点可能比纯粹的SAX稍微复杂一些。 ○ 适用场景适合需要处理中等大小的XML文档同时保持较低内存占用的情况。
4. XPath解析器
○ 优点提供了强大的查询功能能够方便地定位XML文档中的元素和数据。 ○ 缺点可能会稍微降低性能特别是在复杂的查询情况下。 ○ 适用场景适合需要定位和提取特定数据的情况可以减少手动遍历和解析的工作。
5. JSON对应XML解析器
○ 优点可以将XML数据转换为JSON格式利用JSON解析器处理。 ○ 缺点可能会导致数据结构转换复杂性不是所有情况下都适用。 ○ 适用场景当您的应用程序使用JSON格式处理数据但需要处理XML数据时可以考虑此类解析器。
解析的jacoco XML数据量较多 行数至几十万行 XML大小为 数十M 选择SAX解析器进行解析
2 解析思路
SAX可以逐行处理标签
/*** author xieyan* date 2023-08-22 16:13*/
public class JacocoXmlConstant {public static final String COUNTER counter;public static final String METHOD method;public static final String CLASS class;public static final String SOURCEFILE sourcefile;public static final String SOURCEFILE_NAME name;public static final String COUNTER_TYPE type;public static final String COUNTER_MISSED missed;public static final String COUNTER_COVERED covered;public static final String METHOD_NAME name;public static final String METHOD_DESC desc;public static final String CLASS_NAME name;public static final String CLASS_SOURCEFILENAME sourcefilename;public static final String REPORT_NAME name;public static final String PACKAGE_NAME name;public static final String REPORT report;public static final String PACKAGE package;public static final String SESSIONINFO sessioninfo;public static final String LINE line;public static final String INSTRUCTION_TYPE INSTRUCTION;public static final String BRANCH_TYPE BRANCH;public static final String LINE_TYPE LINE;public static final String COMPLEXITY_TYPE COMPLEXITY;public static final String METHOD_TYPE METHOD;public static final String CLASS_TYPE CLASS;}import lombok.Getter;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;import java.util.List;import static com.jacoco.xml.JacocoXmlConstant.*;/*** 解析xml文件** author xieyan*/
Getter
public class ParseXmlHandler extends DefaultHandler {private Report report;private Package currentPackage;private Clazz currentClass;private Method currentMethod;private Counter currentCounter;private String sourcefile;/*** 开始解析元素时触发*/Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) {switch (qName) {// 跳过 sessioninfo 和 linecase SESSIONINFO:case LINE:return;// 解析reportcase REPORT:report new Report();report.setName(attributes.getValue(REPORT_NAME));break;// 解析packagecase PACKAGE:currentPackage new Package();currentPackage.setName(attributes.getValue(PACKAGE_NAME));if (report ! null) {report.addPackage(currentPackage);}break;// 解析classcase CLASS:currentClass new Clazz();currentClass.setName(attributes.getValue(CLASS_NAME));currentClass.setSourcefilename(attributes.getValue(CLASS_SOURCEFILENAME));if (currentPackage ! null) {currentPackage.addClass(currentClass);}break;// 解析methodcase METHOD:currentMethod new Method();currentMethod.setName(attributes.getValue(METHOD_NAME));currentMethod.setDesc(attributes.getValue(METHOD_DESC));if (currentClass ! null) {currentClass.addMethod(currentMethod);}break;// 解析sourcefilecase SOURCEFILE:sourcefile attributes.getValue(SOURCEFILE_NAME);break;// 解析countercase COUNTER:currentCounter new Counter();currentCounter.setType(attributes.getValue(COUNTER_TYPE));currentCounter.setMissed(Integer.parseInt(attributes.getValue(COUNTER_MISSED)));currentCounter.setCovered(Integer.parseInt(attributes.getValue(COUNTER_COVERED)));// 绑定counter 到对应的元素bindCounter();break;default:break;}}/*** 结束解析元素时触发*/Overridepublic void endElement(String uri, String localName, String qName) {switch (qName) {case SESSIONINFO:case LINE:// 跳过 sessioninfo 和 linereturn;case SOURCEFILE:// 避免重复加入 counter 到 pagesourcefile null;break;case REPORT:// 计算总的覆盖率Coverage coverageReport caculateCoverage(report.getReportCounters());report.setReportCoverage(coverageReport);break;case PACKAGE:// 计算 package 覆盖率if (currentPackage ! null) {Coverage coveragePackage caculateCoverage(currentPackage.getPackageCounters());currentPackage.setPackageCoverage(coveragePackage);currentPackage null;}break;case CLASS:// 计算 class 覆盖率if (currentClass ! null) {Coverage coverageClass caculateCoverage(currentClass.getClazzCounters());currentClass.setClazzCoverage(coverageClass);currentClass null;}break;case METHOD:// 计算 method 覆盖率if (currentMethod ! null) {Coverage coverageMethod caculateCoverage(currentMethod.getMethodCounters());currentMethod.setMethodCoverage(coverageMethod);currentMethod null;}break;case COUNTER:currentCounter null;break;default:break;}}/*** 绑定counter 到对应的元素*/private void bindCounter() {// counter 属于 methodif (currentMethod ! null) {currentMethod.addCounter(currentCounter);}// counter 属于 classelse if (currentClass ! null) {currentClass.addCounter(currentCounter);}// counter 属于 packageelse if (currentPackage ! null) {// 跳过sourcefile里的counter 避免重复加入if (sourcefile null) {currentPackage.addCounter(currentCounter);}}// counter 属于 reportelse if (report ! null) {report.addCounter(currentCounter);}}/*** 计算覆盖率*/private Coverage caculateCoverage(ListCounter counterList) {Coverage result new Coverage();for (Counter counter : counterList) {String type counter.getType().toUpperCase();String coverage processResult(counter);setCoverageByType(result, type, coverage);}return result;}private void setCoverageByType(Coverage result, String type, String coverage) {switch (type) {// 指令覆盖率case INSTRUCTION_TYPE:result.setInstructionCoverage(coverage);break;// 行覆盖率case LINE_TYPE:result.setLineCoverage(coverage);break;// 分支覆盖率case BRANCH_TYPE:result.setBranchCoverage(coverage);break;// 圈复杂度覆盖率case COMPLEXITY_TYPE:result.setComplexityCoverage(coverage);break;// 方法覆盖率case METHOD_TYPE:result.setMethodCoverage(coverage);break;// 类覆盖率case CLASS_TYPE:result.setClassCoverage(coverage);break;default:break;}}/*** 处理覆盖率结果* 保留两位小数 例如 99.99%*/private String processResult(Counter counter) {int missed counter.getMissed();int covered counter.getCovered();double coverage (double) covered / (missed covered);double coveragePercentage coverage * 100;return String.format(%.2f%%, coveragePercentage);}}import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** author xieyan*/
Data
public class Clazz {private String name;private String sourcefilename;private final ListMethod methods new ArrayList();private final ListCounter clazzCounters new ArrayList();private Coverage clazzCoverage;public void addMethod(Method method) {methods.add(method);}public void addCounter(Counter counter) {clazzCounters.add(counter);}}import lombok.Data;/*** author xieyan*/
Data
public class Counter {private String type;private int missed;private int covered;}import lombok.Data;/*** 覆盖率统计* author xieyan* date 2021-08-22 16:13*/
Data
public class Coverage {/*** 指令覆盖率*/private String instructionCoverage;/** * 分支覆盖率*/private String branchCoverage;/*** 行覆盖率*/private String lineCoverage;/*** 圈复杂度覆盖率*/private String complexityCoverage;/*** 方法覆盖率 */private String methodCoverage;/*** 类覆盖率*/private String classCoverage;
}Method
import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** author xieyan*/
Data
public class Method {private String name;private String desc;private final ListCounter methodCounters new ArrayList();private Coverage methodCoverage;public void addCounter(Counter counter) {methodCounters.add(counter);}}import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** author xieyan*/
Data
public class Package {private String name;private final ListClazz classes new ArrayList();private final ListCounter packageCounters new ArrayList();private Coverage packageCoverage;public void addClass(Clazz clazz) {classes.add(clazz);}public void addCounter(Counter counter) {packageCounters.add(counter);}}Data
public class Report {private String name;private final ListPackage packages new ArrayList();private final ListCounter reportCounters new ArrayList();private Coverage reportCoverage;public void addPackage(Package pkg) {packages.add(pkg);}public void addCounter(Counter counter) {reportCounters.add(counter);}}import lombok.extern.slf4j.Slf4j;
import org.xml.sax.SAXException;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;/*** 解析jacoco覆盖率报告工具类* author xieyan* date 2023-08-22 16:38*/
Slf4j
public class ParseJacocoXmlUtil {/*** 解析jacoco覆盖率报告** param xmlPath jacoco覆盖率报告路径* return 解析后的报告对象解析失败时返回null*/public static Report parse(String xmlPath) {try {SAXParserFactory factory SAXParserFactory.newInstance();// 禁用DTD验证factory.setFeature(http://apache.org/xml/features/nonvalidating/load-external-dtd, false);SAXParser saxParser factory.newSAXParser();// 读取xml文件File xmlFile new File(xmlPath);ParseXmlHandler handler new ParseXmlHandler();try (InputStream inputStream xmlFile.toURI().toURL().openStream()) {// 解析XML文件saxParser.parse(inputStream, handler);return handler.getReport();}} catch (ParserConfigurationException | SAXException | IOException e) {log.error(解析jacoco xml 覆盖率报告失败, e);}return null;}
}public class SaxParsingToJavaObjectExample {public static void main(String[] args) {// 指定XML文件路径String xmlFilePath D:\\tmp\\jacoco.xml;//String xmlFilePath F:\\temp\\a.xml;Report report ParseJacocoXmlUtil.parse(xmlFilePath);Optional.ofNullable(report).ifPresent(SaxParsingToJavaObjectExample::export);}public static void export(Report report) {for (Package pkg : report.getPackages()) {System.out.println(Package Name: pkg.getName());for (Clazz clazz : pkg.getClasses()) {System.out.println(Class Name: clazz.getName());for (Method method : clazz.getMethods()) {System.out.println(Method Name: method.getName());System.out.println(Method Description: method.getDesc());for (Counter counter : method.getMethodCounters()) {System.out.println(Counter Type: counter.getType());System.out.println(Counter Missed: counter.getMissed());System.out.println(Counter Covered: counter.getCovered() \n);}System.out.println( Method );}}}}
}