July, 19(R)

July, 19

1. Ripe 熟的 cherry 樱桃 pork chop猪排 ham 火腿 sausage 香肠 poultry 家禽 liver 肝 giblets 内脏杂件 lobster龙虾 crab螃蟹 strawberry草莓 check-out stand 付款台

2. Could you do me a favor? 请你帮我一个忙好吗?

3. I am a little nervous about choosing meat. 我对挑肉有些担心。

4. This brand of coffee is on sale today, I’d like to have some. 这个牌子的咖啡在减价,我想买些回来。

5. I’ll look around and see if there is anything I need.我四处走走,看看有没有什么要买的。

6. I don’t want to buy anything, just browsing.我不想买什么,随便看看。

7. Will you help me for a minute? 请帮我一点忙,好吗?

该数据集通过合成方式模拟了多种发动机在运行过程中的传感器监测数据,旨在构建一个用于机械系统故障检测的基准资源,特别适用于汽车领域的诊断分析。数据按固定时间间隔采集,涵盖了发动机性能指标、异常状态以及工作模式等多维度信息。 时间戳:数据类型为日期时间,记录了每个数据点的采集时刻。序列起始于2024年12月24日10:00,并以5分钟为间隔持续生成,体现了对发动机运行状态的连续监测。 温度(摄氏度):以浮点数形式记录发动机的温度读数。其数值范围通常处于60至120摄氏度之间,反映了发动机在常规工况下的典型温度区间。 转速(转/分钟):以浮点数表示发动机曲轴的旋转速度。该参数在1000至4000转/分钟的范围内随机生成,符合多数发动机在正常运转时的转速特征。 燃油效率(公里/升):浮点型变量,用于衡量发动机的燃料利用效能,即每升燃料所能支持的行驶里程。其取值范围设定在15至30公里/升之间。 振动_X、振动_Y、振动_Z:这三个浮点数列分别记录了发动机在三维空间坐标系中各轴向的振动强度。测量值标准化至0到1的标度,较高的数值通常暗示存在异常振动,可能与潜在的机械故障相关。 扭矩(牛·米):以浮点数表征发动机输出的旋转力矩,数值区间为50至200牛·米,体现了发动机的负载能力。 功率输出(千瓦):浮点型变量,描述发动机单位时间内做功的速率,取值范围为20至100千瓦。 故障状态:整型分类变量,用于标识发动机的异常程度,共分为四个等级:0代表正常状态,1表示轻微故障,2对应中等故障,3指示严重故障。该列作为分类任务的目标变量,支持基于传感器数据预测故障等级。 运行模式:字符串类型变量,描述发动机当前的工作状态,主要包括:怠速(发动机运转但无负载)、巡航(发动机在常规负载下平稳运行)、重载(发动机承受高负荷或高压工况)。 数据集整体包含1000条记录,每条记录对应特定时刻的发动机性能快照。其中故障状态涵盖从正常到严重故障的四级分类,有助于训练模型实现故障预测与诊断。所有数据均为合成生成,旨在模拟真实的发动机性能变化与典型故障场景,所包含的温度、转速、燃油效率、振动、扭矩及功率输出等关键传感指标,均为影响发动机故障判定的重要因素。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
<think>我们注意到在原始数据中,有两个主要的参数部分(Param): 1. ImageMaster - Certificate 2. Measurement Parameter: Tilt Corrected MTF @ Best/TF1 每个部分都有自己的标题(title)和一组键值对。 因此,我们需要调整解析策略,将整个文档视为多个参数部分(而不仅仅是证书部分和其他部分)。每个参数部分由一个标题和一组键值对(可能出现在段落或表格中)组成。 修改方案: 1. 在解析参数部分时,不再只解析预定义的部分,而是动态识别所有参数部分。 2. 使用一个列表来存储所有遇到的参数部分,然后根据标题映射到我们数据结构中的特定成员。 但是,我们的数据结构(tagParameterSections)是固定的,因此我们需要将每个解析出来的参数部分根据标题映射到对应的成员。 步骤: 1. 遍历文档,识别标题(通常是加粗、大字号或独立的文本块)。 2. 当遇到一个标题时,开始一个新的参数部分,直到遇到下一个标题。 3. 在标题之间的内容中提取键值对(包括段落和表格)。 由于数据结构中已经预定义了多个部分(如tagMTFvsImageHeight等),我们可以创建一个映射表,将标题字符串映射到对应的成员。 例如: "ImageMaster - Certificate" -> 这个部分的数据应该存储在哪里?注意,我们的数据结构中没有专门为证书设置的参数部分,证书部分已经单独用tagCertificate结构存储了。 因此,我们需要重新考虑: 实际上,证书部分(ImageMaster - Certificate)已经在parseCertificateInfo中解析了,所以不应该再作为参数部分出现。 所以,参数部分应该是除证书部分以外的其他部分,如"Tilt Corrected MTF"等。 修改后的参数部分解析逻辑: 1. 跳过证书部分(因为已经解析过了)。 2. 对于其他部分,根据标题映射到tagParameterSections中的成员。 但是,原始数据中参数部分的标题是"Measurement Parameter: Tilt Corrected MTF @ Best/TF1",而我们的映射表中可能是"Tilt Corrected MTF"。 因此,我们需要一个更灵活的映射方式,比如使用包含关系(例如,标题中包含"Tilt Corrected MTF"就映射到tagTiltCorrectedMTF)。 具体调整: 1. 在parseParameterSections函数中,我们遍历文档,寻找可能是参数部分标题的文本块。 2. 当找到一个标题时,检查它是否包含我们预定义的关键字(例如,对于tagTiltCorrectedMTF,我们可能定义关键字为"Tilt Corrected MTF")。 3. 然后,将这个标题之后直到下一个标题的内容作为该参数部分的内容,从中提取键值对。 同时,由于证书部分已经单独解析,我们可以在遍历时跳过证书部分。 实现: 步骤: a. 创建一个映射表,将关键字映射到参数成员指针。 b. 遍历文档的文本块。 c. 如果文本块是证书部分的标题,跳过(因为证书部分已经解析)。 d. 如果文本块包含某个关键字,则将其识别为参数部分标题,并设置当前活动部分。 e. 在活动部分中,提取键值对(包括表格)。 注意:一个参数部分可能包含多个段落和表格。 修改后的parseParameterSections函数: 伪代码: QMap<QString, tagMeasurementParameter*> paramMap; // 关键字到成员的映射 QString currentKey; // 当前活动的关键字 tagMeasurementParameter* currentParam = nullptr; for (each block) { QString text = block.text().trimmed(); // 检查是否是证书部分标题,如果是则跳过 if (text.contains("ImageMaster - Certificate")) { currentParam = nullptr; continue; } // 检查是否是参数部分标题 if (text.startsWith("Measurement Parameter:")) { // 提取实际部分名称,例如"Tilt Corrected MTF @ Best/TF1" QString sectionName = text.mid(23).trimmed(); // 在映射表中查找包含的关键字 currentKey = ""; for (auto it = paramMap.begin(); it != paramMap.end(); ++it) { if (sectionName.contains(it.key())) { currentKey = it.key(); break; } } if (!currentKey.isEmpty()) { currentParam = paramMap[currentKey]; currentParam->title = sectionName; // 存储完整的标题 } else { currentParam = nullptr; } continue; } // 如果当前在参数部分内,解析键值对 if (currentParam) { // 从文本块中提取键值对 extractKeyValuePairs(text, currentParam->param); // 检查文本块关联的表格 QTextTable* table = ...; if (table) { extractKeyValueTable(table, currentParam->param); } } } 但是,注意:参数部分可能有多个段落,并且可能跨多个文本块。 另外,我们还需要考虑证书部分已经解析过,所以跳过整个证书部分。但是,证书部分在文档中的位置可能不固定,所以我们可以通过标题来识别。 因此,我们修改解析流程: 1. 首先,解析证书部分(使用之前的方法,因为它包含特定的字段)。 2. 然后,解析参数部分,跳过已经解析过的证书部分。 在参数部分解析中,我们只处理以"Measurement Parameter:"开头的部分。 同时,我们需要定义映射表的关键字。例如: paramMap["MTF vs Image Height"] = &params.tagMTFvsImageHeight; paramMap["MTF vs Object Angle"] = &params.tagMTFvsObjectAngle; ... paramMap["Tilt Corrected MTF"] = &params.tagTiltCorrectedMTF; 注意:原始数据中的标题可能是"Tilt Corrected MTF @ Best/TF1",但我们的关键字是"Tilt Corrected MTF",这样就能匹配。 具体代码实现: 由于时间关系,这里只给出关键部分的修改,其他部分(如图表、表格)可以类似处理。 下面修改parseParameterSections函数:</think># MHT文档解析优化方案:多参数部分处理 根据您提供的新信息,我理解到MHT文档包含多个独立的参数部分,每个部分都有自己的标题和键值对数据。以下是针对这种结构的优化解析方案: ```cpp #include <QTextDocument> #include <QTextTable> #include <QTextFrame> #include <QTextBlock> #include <QRegularExpression> #include <QDebug> // 定义数据结构(根据您提供的内容) struct tagImageMasterCertificate { QString title; QString company; QString operatorName; QDateTime dateTime; QString sampleId; QString measureProgram; QString temperature; QString measuredwith; QString instrumentSN; QString comments; }; struct tagMeasurementParameter { QString title; QMap<QString, QString> param; }; struct tagParameterSections { // 使用QMap存储所有参数部分,键为标题 QMap<QString, tagMeasurementParameter> sections; // 添加辅助方法获取特定部分 tagMeasurementParameter* getSection(const QString& title) { if (!sections.contains(title)) { sections[title] = tagMeasurementParameter{title, {}}; } return &sections[title]; } }; // 其他数据结构保持不变... class MeasurementParser { public: tagMeasurement parseDocument(QTextDocument* doc, const QString& filePath) { tagMeasurement measurement; measurement.fileName = QFileInfo(filePath).fileName(); // 1. 解析主证书信息 parseCertificateInfo(doc, measurement.tagCertificate); // 2. 解析所有参数部分 parseAllParameterSections(doc, measurement.tagParam); // 3. 解析图表部分 parseGraphSections(doc, measurement.tagGraph); // 4. 解析表格部分 parseTableSections(doc, measurement.tagTable); return measurement; } private: // 解析主证书信息 void parseCertificateInfo(QTextDocument* doc, tagImageMasterCertificate& cert) { // 查找证书部分标题 QTextBlock certificateBlock = findSectionBlock(doc, "ImageMaster - Certificate"); if (!certificateBlock.isValid()) return; // 解析证书内容 QTextBlock currentBlock = certificateBlock.next(); while (currentBlock.isValid()) { QString text = currentBlock.text().trimmed(); // 检查是否到达下一个部分 if (text.startsWith("Measurement Parameter:")) break; // 解析键值对 parseKeyValuePair(text, cert); // 检查表格 QTextTable* table = qobject_cast<QTextTable*>(doc->objectForFormat(currentBlock.blockFormat())); if (table) { parseCertificateTable(table, cert); } currentBlock = currentBlock.next(); } } // 解析所有参数部分 void parseAllParameterSections(QTextDocument* doc, tagParameterSections& params) { QTextBlock currentBlock = doc->begin(); while (currentBlock.isValid()) { QString text = currentBlock.text().trimmed(); // 检测参数部分标题 if (text.startsWith("Measurement Parameter:")) { QString sectionTitle = text; tagMeasurementParameter* section = params.getSection(sectionTitle); // 移动到内容部分 currentBlock = currentBlock.next(); // 解析该部分内容 while (currentBlock.isValid()) { QString content = currentBlock.text().trimmed(); // 检查是否到达下一个部分 if (content.startsWith("Measurement Parameter:")) break; // 解析键值对 extractKeyValuePairs(content, section->param); // 检查表格 QTextTable* table = qobject_cast<QTextTable*>(doc->objectForFormat(currentBlock.blockFormat())); if (table) { extractKeyValueTable(table, section->param); } currentBlock = currentBlock.next(); } // 处理完一个部分后继续,但不要跳过当前块 continue; } currentBlock = currentBlock.next(); } } // 解析键值对到证书结构 void parseKeyValuePair(const QString& text, tagImageMasterCertificate& cert) { QRegularExpression re; re.setPattern(R"(Company\s*[::]\s*(.+))"); QRegularExpressionMatch match = re.match(text); if (match.hasMatch()) cert.company = match.captured(1).trimmed(); re.setPattern(R"(Operator\s*[::]\s*(.+))"); match = re.match(text); if (match.hasMatch()) cert.operatorName = match.captured(1).trimmed(); re.setPattern(R"(Time/Date\s*[::]\s*(\d{2}:\d{2}:\d{2}\s+\w+\s+\d{1,2},\s+\d{4}))"); match = re.match(text); if (match.hasMatch()) { cert.dateTime = QDateTime::fromString(match.captured(1), "HH:mm:ss MMMM d, yyyy"); } re.setPattern(R"(Sample ID\s*[::]\s*(\w+))"); match = re.match(text); if (match.hasMatch()) cert.sampleId = match.captured(1).trimmed(); re.setPattern(R"(Measure Program\s*[::]\s*(.+))"); match = re.match(text); if (match.hasMatch()) cert.measureProgram = match.captured(1).trimmed(); re.setPattern(R"(Temperature\s*[::]\s*([\d.]+)\s*°C)"); match = re.match(text); if (match.hasMatch()) cert.temperature = match.captured(1).trimmed(); re.setPattern(R"(Measured with\s*[::]\s*(.+))"); match = re.match(text); if (match.hasMatch()) cert.measuredwith = match.captured(1).trimmed(); re.setPattern(R"(Instrument S/N\s*[::]\s*(\w+))"); match = re.match(text); if (match.hasMatch()) cert.instrumentSN = match.captured(1).trimmed(); re.setPattern(R"(Comments\s*[::]\s*(.+))"); match = re.match(text); if (match.hasMatch()) cert.comments = match.captured(1).trimmed(); } // 查找指定标题的文本块 QTextBlock findSectionBlock(QTextDocument* doc, const QString& title) { QTextBlock block = doc->begin(); while (block.isValid()) { if (block.text().contains(title)) { return block; } block = block.next(); } return QTextBlock(); } // 从文本提取键值对 void extractKeyValuePairs(const QString& text, QMap<QString, QString>& params) { QRegularExpression re(R"(([^::]+?)\s*[::]\s*([^\n]+))"); QRegularExpressionMatchIterator it = re.globalMatch(text); while (it.hasNext()) { QRegularExpressionMatch match = it.next(); QString key = match.captured(1).trimmed(); QString value = match.captured(2).trimmed(); // 跳过空键或空值 if (!key.isEmpty() && !value.isEmpty()) { params[key] = value; } } } // 从表格提取键值对 void extractKeyValueTable(QTextTable* table, QMap<QString, QString>& params) { const int rows = table->rows(); for (int row = 0; row < rows; ++row) { if (table->columns() < 2) continue; QString key = table->cellAt(row, 0).text().trimmed(); QString value = table->cellAt(row, 1).text().trimmed(); if (!key.isEmpty() && !value.isEmpty()) { params[key] = value; } } } // 解析证书表格 void parseCertificateTable(QTextTable* table, tagImageMasterCertificate& cert) { const int rows = table->rows(); const int cols = table->columns(); for (int row = 0; row < rows; ++row) { QString key = table->cellAt(row, 0).text().trimmed(); QString value = (cols > 1) ? table->cellAt(row, 1).text().trimmed() : ""; if (key == "Company") cert.company = value; else if (key == "Operator") cert.operatorName = value; else if (key == "Time/Date") { cert.dateTime = QDateTime::fromString(value, "HH:mm:ss MMMM d, yyyy"); } else if (key == "Sample ID") cert.sampleId = value; else if (key == "Measure Program") cert.measureProgram = value; else if (key == "Temperature") cert.temperature = value; else if (key == "Measured with") cert.measuredwith = value; else if (key == "Instrument S/N") cert.instrumentSN = value; else if (key == "Comments") cert.comments = value; } } // 其他解析函数保持不变... }; // 示例使用 void processDocument() { // 创建文档 QTextDocument doc; doc.setHtml("<html><body>" "<h1>ImageMaster - Certificate</h1>" "<p>Company: Sunex</p>" "<p>Operator: TH</p>" "<p>Time/Date: 19:09:56 July 04, 2025</p>" "<p>Sample ID: 0</p>" "<p>Measure Program: 3D Tilt Corrected Through Focus</p>" "<p>Temperature: 20°C</p>" "<p>Measured with: TRIOPTICS - MTF-LAB - Vers. 5.13.2</p>" "<p>Instrument S/N: 09-113-0259</p>" "<p>Comments: AMT5</p>" "<h2>Measurement Parameter: Tilt Corrected MTF @ Best/TF1</h2>" "<p>Setup Type: Object Infinite / Image Finite</p>" "<p>EFL (Collimator): 50 mm</p>" "<p>Wavelength: 560 nm (PE)</p>" "<p>EFL (Sample): 1.0506 mm</p>" "<p>F-Number: 2.0000</p>" "<p>Focus Position: 41.6582 mm</p>" "<p>Optimize Freq.: 100.0 lp/mm</p>" "<p>Best Focus TF1: 41.6582 mm</p>" "</body></html>"); // 解析文档 MeasurementParser parser; tagMeasurement measurement = parser.parseDocument(&doc, "sample.mht"); // 输出结果 qDebug() << "Certificate Info:"; qDebug() << " Company:" << measurement.tagCertificate.company; qDebug() << " Operator:" << measurement.tagCertificate.operatorName; qDebug() << " Date/Time:" << measurement.tagCertificate.dateTime.toString(); qDebug() << " Measure Program:" << measurement.tagCertificate.measureProgram; qDebug() << "\nParameter Sections:"; for (auto it = measurement.tagParam.sections.begin(); it != measurement.tagParam.sections.end(); ++it) { qDebug() << "Section:" << it.key(); for (auto paramIt = it->param.begin(); paramIt != it->param.end(); ++paramIt) { qDebug() << " " << paramIt.key() << ":" << paramIt.value(); } } } // 调用示例 int main() { processDocument(); return 0; } ``` ## 解决方案解析 ### 1. 数据结构优化 ```cpp struct tagParameterSections { // 使用QMap存储所有参数部分,键为标题 QMap<QString, tagMeasurementParameter> sections; // 添加辅助方法获取特定部分 tagMeasurementParameter* getSection(const QString& title) { if (!sections.contains(title)) { sections[title] = tagMeasurementParameter{title, {}}; } return &sections[title]; } }; ``` - 使用`QMap`动态存储多个参数部分 - 每个参数部分由其标题唯一标识 - `getSection()`方法确保始终返回有效的部分指针 ### 2. 多部分解析流程 #### 证书部分解析 ```cpp void parseCertificateInfo(QTextDocument* doc, tagImageMasterCertificate& cert) { // 查找证书部分标题 QTextBlock certificateBlock = findSectionBlock(doc, "ImageMaster - Certificate"); if (!certificateBlock.isValid()) return; // 解析证书内容 QTextBlock currentBlock = certificateBlock.next(); while (currentBlock.isValid()) { QString text = currentBlock.text().trimmed(); // 检查是否到达下一个部分 if (text.startsWith("Measurement Parameter:")) break; // 解析键值对 parseKeyValuePair(text, cert); // 检查表格 QTextTable* table = qobject_cast<QTextTable*>(doc->objectForFormat(currentBlock.blockFormat())); if (table) { parseCertificateTable(table, cert); } currentBlock = currentBlock.next(); } } ``` - 精确定位"ImageMaster - Certificate"部分 - 遍历该部分的所有内容块 - 遇到下一个参数部分标题时停止解析 #### 参数部分解析 ```cpp void parseAllParameterSections(QTextDocument* doc, tagParameterSections& params) { QTextBlock currentBlock = doc->begin(); while (currentBlock.isValid()) { QString text = currentBlock.text().trimmed(); // 检测参数部分标题 if (text.startsWith("Measurement Parameter:")) { QString sectionTitle = text; tagMeasurementParameter* section = params.getSection(sectionTitle); // 移动到内容部分 currentBlock = currentBlock.next(); // 解析该部分内容 while (currentBlock.isValid()) { QString content = currentBlock.text().trimmed(); // 检查是否到达下一个部分 if (content.startsWith("Measurement Parameter:")) break; // 解析键值对 extractKeyValuePairs(content, section->param); // 检查表格 QTextTable* table = qobject_cast<QTextTable*>(doc->objectForFormat(currentBlock.blockFormat())); if (table) { extractKeyValueTable(table, section->param); } currentBlock = currentBlock.next(); } // 处理完一个部分后继续,但不要跳过当前块 continue; } currentBlock = currentBlock.next(); } } ``` - 扫描整个文档查找"Measurement Parameter:"开头的标题 - 为每个参数部分创建独立的数据结构 - 解析直到遇到下一个参数部分标题 - 支持表格和文本混合内容 ### 3. 键值对解析增强 ```cpp void parseKeyValuePair(const QString& text, tagImageMasterCertificate& cert) { QRegularExpression re; re.setPattern(R"(Time/Date\s*[::]\s*(\d{2}:\d{2}:\d{2}\s+\w+\s+\d{1,2},\s+\d{4}))"); match = re.match(text); if (match.hasMatch()) { cert.dateTime = QDateTime::fromString(match.captured(1), "HH:mm:ss MMMM d, yyyy"); } // 其他字段... } ``` - 增强日期时间解析,支持"19:09:56 July 04, 2025"格式 - 使用更灵活的正则表达式处理中英文分隔符 - 支持带单位的数值解析(如温度"20°C") ### 4. 表格解析优化 ```cpp void extractKeyValueTable(QTextTable* table, QMap<QString, QString>& params) { const int rows = table->rows(); for (int row = 0; row < rows; ++row) { if (table->columns() < 2) continue; QString key = table->cellAt(row, 0).text().trimmed(); QString value = table->cellAt(row, 1).text().trimmed(); // 处理带单位的数值 if (key.contains("Temperature") && !value.contains("°C")) { value += "°C"; } if (!key.isEmpty() && !value.isEmpty()) { params[key] = value; } } } ``` - 自动补充缺失的单位信息 - 处理不同列数的表格 - 跳过空行和无效数据 ## 数据处理与验证 ### 1. 数据完整性检查 ```cpp void validateMeasurement(tagMeasurement& measurement) { // 检查证书部分必要字段 if (measurement.tagCertificate.company.isEmpty() || measurement.tagCertificate.operatorName.isEmpty() || !measurement.tagCertificate.dateTime.isValid()) { qWarning() << "Certificate information is incomplete"; } // 检查参数部分 for (auto& section : measurement.tagParam.sections) { if (section.param.isEmpty()) { qWarning() << "Parameter section" << section.title << "is empty"; } // 检查关键参数 if (section.title.contains("Tilt Corrected MTF")) { if (!section.param.contains("Focus Position") || !section.param.contains("Optimize Freq.")) { qWarning() << "Missing critical parameters in" << section.title; } } } } ``` ### 2. 单位标准化 ```cpp void normalizeUnits(tagMeasurement& measurement) { // 标准化温度单位 if (!measurement.tagCertificate.temperature.contains("°C")) { measurement.tagCertificate.temperature += "°C"; } // 标准化参数部分单位 for (auto& section : measurement.tagParam.sections) { for (auto it = section.param.begin(); it != section.param.end(); ++it) { if (it.key().contains("Wavelength") && !it.value().contains("nm")) { it.value() += " nm"; } else if (it.key().contains("Freq.") && !it.value().contains("lp/mm")) { it.value() += " lp/mm"; } } } } ``` ### 3. 数据转换工具 ```cpp class MeasurementConverter { public: // 将测量数据转换为JSON格式 QJsonObject toJson(const tagMeasurement& measurement) { QJsonObject root; // 证书部分 QJsonObject certificate; certificate["title"] = measurement.tagCertificate.title; certificate["company"] = measurement.tagCertificate.company; certificate["operator"] = measurement.tagCertificate.operatorName; certificate["dateTime"] = measurement.tagCertificate.dateTime.toString(Qt::ISODate); // 其他字段... root["certificate"] = certificate; // 参数部分 QJsonObject parameters; for (auto& section : measurement.tagParam.sections) { QJsonObject sectionObj; for (auto it = section.param.begin(); it != section.param.end(); ++it) { sectionObj[it.key()] = it.value(); } parameters[section.title] = sectionObj; } root["parameters"] = parameters; return root; } // 从JSON导入测量数据 tagMeasurement fromJson(const QJsonObject& json) { tagMeasurement measurement; // 解析证书部分 QJsonObject certificate = json["certificate"].toObject(); measurement.tagCertificate.title = certificate["title"].toString(); measurement.tagCertificate.company = certificate["company"].toString(); measurement.tagCertificate.operatorName = certificate["operator"].toString(); measurement.tagCertificate.dateTime = QDateTime::fromString( certificate["dateTime"].toString(), Qt::ISODate); // 其他字段... // 解析参数部分 QJsonObject parameters = json["parameters"].toObject(); for (auto it = parameters.begin(); it != parameters.end(); ++it) { QString sectionTitle = it.key(); QJsonObject sectionObj = it.value().toObject(); tagMeasurementParameter* section = measurement.tagParam.getSection(sectionTitle); for (auto paramIt = sectionObj.begin(); paramIt != sectionObj.end(); ++paramIt) { section->param[paramIt.key()] = paramIt.value().toString(); } } return measurement; } }; ``` ## 性能优化策略 ### 1. 增量解析与状态机 ```cpp class ParserStateMachine { public: enum State { Start, InCertificate, InParameterSection, InGraphSection, InTableSection }; ParserStateMachine() : currentState(Start) {} void processBlock(const QTextBlock& block) { QString text = block.text().trimmed(); switch (currentState) { case Start: if (text.contains("ImageMaster - Certificate")) { currentState = InCertificate; // 开始解析证书部分 } else if (text.startsWith("Measurement Parameter:")) { currentState = InParameterSection; // 开始解析参数部分 } break; case InCertificate: if (text.startsWith("Measurement Parameter:")) { currentState = InParameterSection; } // 解析证书内容... break; case InParameterSection: if (text.startsWith("Measurement Parameter:")) { // 开始新的参数部分 } else if (text.contains("Graph Section")) { currentState = InGraphSection; } // 解析参数内容... break; // 其他状态处理... } } private: State currentState; }; ``` ### 2. 并行处理多个部分 ```cpp void parseDocumentParallel(QTextDocument* doc, tagMeasurement& measurement) { // 创建并行任务 QFuture<void> certificateFuture = QtConcurrent::run([&] { parseCertificateInfo(doc, measurement.tagCertificate); }); QFuture<void> parametersFuture = QtConcurrent::run([&] { parseAllParameterSections(doc, measurement.tagParam); }); QFuture<void> graphsFuture = QtConcurrent::run([&] { parseGraphSections(doc, measurement.tagGraph); }); QFuture<void> tablesFuture = QtConcurrent::run([&] { parseTableSections(doc, measurement.tagTable); }); // 等待所有任务完成 certificateFuture.waitForFinished(); parametersFuture.waitForFinished(); graphsFuture.waitForFinished(); tablesFuture.waitForFinished(); } ``` ### 3. 内存映射文件处理 ```cpp class MappedDocumentParser { public: MappedDocumentParser(const QString& filePath) { file.setFileName(filePath); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open file:" << filePath; return; } mappedData = file.map(0, file.size()); if (!mappedData) { qWarning() << "Failed to map file:" << filePath; return; } } ~MappedDocumentParser() { if (mappedData) file.unmap(mappedData); file.close(); } void parse(tagMeasurement& measurement) { if (!mappedData) return; // 直接处理内存映射数据 const char* data = static_cast<const char*>(mappedData); qint64 size = file.size(); // 查找证书部分 const char* certStart = strstr(data, "ImageMaster - Certificate"); if (certStart) { // 解析证书部分... } // 查找参数部分 const char* paramStart = data; while ((paramStart = strstr(paramStart, "Measurement Parameter:"))) { // 解析参数部分... paramStart++; // 继续查找下一个 } } private: QFile file; uchar* mappedData = nullptr; }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值