Qt C++ 剖析和处置惩罚 XML 文件示例

打印 上一主题 下一主题

主题 1802|帖子 1802|积分 5406

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
使用 Qt C++ 剖析和处置惩罚 XML 文件

以下是使用 Qt C++ 实现 XML 文件处置惩罚的几种方法,包括剖析、创建和修改 XML 文件。
1. 使用 QXmlStreamReader (保举方式)

  1. #include <QFile>
  2. #include <QXmlStreamReader>
  3. #include <QDebug>
  4. void parseXmlWithStream(const QString &filePath) {
  5.     QFile file(filePath);
  6.     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  7.         qDebug() << "无法打开文件:" << filePath;
  8.         return;
  9.     }
  10.     QXmlStreamReader xml(&file);
  11.    
  12.     while (!xml.atEnd()) {
  13.         xml.readNext();
  14.         
  15.         if (xml.isStartElement()) {
  16.             qDebug() << "开始元素:" << xml.name();
  17.             // 打印所有属性
  18.             for (const auto &attr : xml.attributes()) {
  19.                 qDebug() << "  属性:" << attr.name() << "=" << attr.value();
  20.             }
  21.         } else if (xml.isEndElement()) {
  22.             qDebug() << "结束元素:" << xml.name();
  23.         } else if (xml.isCharacters() && !xml.isWhitespace()) {
  24.             qDebug() << "文本内容:" << xml.text().trimmed();
  25.         }
  26.     }
  27.    
  28.     if (xml.hasError()) {
  29.         qDebug() << "XML 解析错误:" << xml.errorString();
  30.     }
  31.    
  32.     file.close();
  33. }
  34. // 使用示例
  35. int main() {
  36.     parseXmlWithStream("example.xml");
  37.     return 0;
  38. }
复制代码
2. 使用 QDomDocument (DOM 方式)

  1. #include <QDomDocument>
  2. #include <QFile>
  3. #include <QDebug>
  4. void parseXmlWithDom(const QString &filePath) {
  5.     QFile file(filePath);
  6.     if (!file.open(QIODevice::ReadOnly)) {
  7.         qDebug() << "无法打开文件:" << filePath;
  8.         return;
  9.     }
  10.    
  11.     QDomDocument doc;
  12.     if (!doc.setContent(&file)) {
  13.         qDebug() << "无法解析 XML 文件";
  14.         file.close();
  15.         return;
  16.     }
  17.    
  18.     file.close();
  19.    
  20.     QDomElement root = doc.documentElement();
  21.     qDebug() << "根元素:" << root.tagName();
  22.    
  23.     // 递归遍历所有节点
  24.     std::function<void(const QDomNode &, int)> traverseNode =
  25.         [&traverseNode](const QDomNode &node, int indent) {
  26.             QDomNode n = node;
  27.             while (!n.isNull()) {
  28.                 qDebug().noquote() << QString(indent, ' ') << "节点:" << n.nodeName();
  29.                
  30.                 if (n.isElement()) {
  31.                     QDomElement e = n.toElement();
  32.                     if (e.hasAttributes()) {
  33.                         QDomNamedNodeMap attrs = e.attributes();
  34.                         for (int i = 0; i < attrs.length(); ++i) {
  35.                             QDomNode attr = attrs.item(i);
  36.                             qDebug().noquote() << QString(indent+2, ' ')
  37.                                               << "属性:" << attr.nodeName()
  38.                                               << "=" << attr.nodeValue();
  39.                         }
  40.                     }
  41.                 }
  42.                
  43.                 if (n.hasChildNodes()) {
  44.                     QDomNode child = n.firstChild();
  45.                     while (!child.isNull()) {
  46.                         if (child.isText()) {
  47.                             QString text = child.nodeValue().trimmed();
  48.                             if (!text.isEmpty()) {
  49.                                 qDebug().noquote() << QString(indent+2, ' ')
  50.                                                   << "文本:" << text;
  51.                             }
  52.                         } else {
  53.                             traverseNode(child, indent+2);
  54.                         }
  55.                         child = child.nextSibling();
  56.                     }
  57.                 }
  58.                
  59.                 n = n.nextSibling();
  60.             }
  61.         };
  62.    
  63.     traverseNode(root.firstChild(), 0);
  64. }
  65. // 使用示例
  66. int main() {
  67.     parseXmlWithDom("example.xml");
  68.     return 0;
  69. }
复制代码
3. 剖析 Qt UI 文件示例

  1. #include <QDomDocument>
  2. #include <QFile>
  3. #include <QDebug>
  4. void parseUiFile(const QString &uiFile) {
  5.     QFile file(uiFile);
  6.     if (!file.open(QIODevice::ReadOnly)) {
  7.         qDebug() << "无法打开 UI 文件:" << uiFile;
  8.         return;
  9.     }
  10.    
  11.     QDomDocument doc;
  12.     if (!doc.setContent(&file)) {
  13.         qDebug() << "无法解析 UI 文件";
  14.         file.close();
  15.         return;
  16.     }
  17.    
  18.     file.close();
  19.    
  20.     QDomElement root = doc.documentElement();
  21.    
  22.     // 查找所有 widget 元素
  23.     QDomNodeList widgets = root.elementsByTagName("widget");
  24.     qDebug() << "找到" << widgets.count() << "个 widget";
  25.    
  26.     for (int i = 0; i < widgets.count(); ++i) {
  27.         QDomElement widget = widgets.at(i).toElement();
  28.         QString name = widget.attribute("name");
  29.         QString className = widget.attribute("class");
  30.         qDebug() << "Widget" << i+1 << ":" << name << "(" << className << ")";
  31.     }
  32.    
  33.     // 查找所有连接
  34.     QDomNodeList connections = root.elementsByTagName("connection");
  35.     qDebug() << "\n找到" << connections.count() << "个连接";
  36.    
  37.     for (int i = 0; i < connections.count(); ++i) {
  38.         QDomElement connection = connections.at(i).toElement();
  39.         QString sender = connection.firstChildElement("sender").text();
  40.         QString signal = connection.firstChildElement("signal").text();
  41.         QString receiver = connection.firstChildElement("receiver").text();
  42.         QString slot = connection.firstChildElement("slot").text();
  43.         qDebug() << "连接" << i+1 << ":" << sender << "." << signal
  44.                 << "->" << receiver << "." << slot;
  45.     }
  46. }
  47. // 使用示例
  48. int main() {
  49.     parseUiFile("mainwindow.ui");
  50.     return 0;
  51. }
复制代码
4. 创建 Qt XML 文件

  1. #include <QDomDocument>
  2. #include <QFile>
  3. #include <QTextStream>
  4. #include <QDebug>
  5. void createQtXml(const QString &outputFile) {
  6.     QDomDocument doc("QtConfig");
  7.    
  8.     // 创建处理指令
  9.     QDomProcessingInstruction instr = doc.createProcessingInstruction(
  10.         "xml", "version="1.0" encoding="UTF-8"");
  11.     doc.appendChild(instr);
  12.    
  13.     // 创建根元素
  14.     QDomElement root = doc.createElement("QtSettings");
  15.     root.setAttribute("version", "1.0");
  16.     doc.appendChild(root);
  17.    
  18.     // 添加窗口设置
  19.     QDomElement window = doc.createElement("Window");
  20.     window.setAttribute("name", "MainWindow");
  21.     root.appendChild(window);
  22.    
  23.     QDomElement width = doc.createElement("Width");
  24.     width.appendChild(doc.createTextNode("800"));
  25.     window.appendChild(width);
  26.    
  27.     QDomElement height = doc.createElement("Height");
  28.     height.appendChild(doc.createTextNode("600"));
  29.     window.appendChild(height);
  30.    
  31.     // 添加按钮设置
  32.     QDomElement button = doc.createElement("Button");
  33.     button.setAttribute("name", "btnOK");
  34.     root.appendChild(button);
  35.    
  36.     QDomElement text = doc.createElement("Text");
  37.     text.appendChild(doc.createTextNode("OK"));
  38.     button.appendChild(text);
  39.    
  40.     // 保存到文件
  41.     QFile file(outputFile);
  42.     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  43.         qDebug() << "无法写入文件:" << outputFile;
  44.         return;
  45.     }
  46.    
  47.     QTextStream stream(&file);
  48.     doc.save(stream, 2);  // 2 表示缩进空格数
  49.     file.close();
  50.    
  51.     qDebug() << "已创建 Qt XML 文件:" << outputFile;
  52. }
  53. // 使用示例
  54. int main() {
  55.     createQtXml("qt_config.xml");
  56.     return 0;
  57. }
复制代码
5. 修改 Qt XML 文件

  1. #include <QDomDocument>
  2. #include <QFile>
  3. #include <QTextStream>
  4. #include <QDebug>
  5. void modifyQtXml(const QString &inputFile, const QString &outputFile) {
  6.     QFile file(inputFile);
  7.     if (!file.open(QIODevice::ReadOnly)) {
  8.         qDebug() << "无法打开文件:" << inputFile;
  9.         return;
  10.     }
  11.    
  12.     QDomDocument doc;
  13.     if (!doc.setContent(&file)) {
  14.         qDebug() << "无法解析 XML 文件";
  15.         file.close();
  16.         return;
  17.     }
  18.    
  19.     file.close();
  20.    
  21.     QDomElement root = doc.documentElement();
  22.    
  23.     // 修改所有 Button 元素的文本
  24.     QDomNodeList buttons = root.elementsByTagName("Button");
  25.     for (int i = 0; i < buttons.count(); ++i) {
  26.         QDomElement button = buttons.at(i).toElement();
  27.         QDomElement textElem = button.firstChildElement("Text");
  28.         if (!textElem.isNull()) {
  29.             QDomNode textNode = textElem.firstChild();
  30.             textNode.setNodeValue("New Text");
  31.         }
  32.     }
  33.    
  34.     // 添加新元素
  35.     QDomElement newButton = doc.createElement("Button");
  36.     newButton.setAttribute("name", "btnCancel");
  37.    
  38.     QDomElement newText = doc.createElement("Text");
  39.     newText.appendChild(doc.createTextNode("Cancel"));
  40.     newButton.appendChild(newText);
  41.    
  42.     root.appendChild(newButton);
  43.    
  44.     // 保存修改
  45.     QFile outFile(outputFile);
  46.     if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
  47.         qDebug() << "无法写入文件:" << outputFile;
  48.         return;
  49.     }
  50.    
  51.     QTextStream stream(&outFile);
  52.     doc.save(stream, 2);
  53.     outFile.close();
  54.    
  55.     qDebug() << "已修改并保存到:" << outputFile;
  56. }
  57. // 使用示例
  58. int main() {
  59.     modifyQtXml("qt_config.xml", "qt_config_modified.xml");
  60.     return 0;
  61. }
复制代码
6. 使用 SAX 剖析器 (QXmlSimpleReader)

  1. #include <QXmlSimpleReader>
  2. #include <QXmlInputSource>
  3. #include <QFile>
  4. #include <QDebug>
  5. class MyXmlHandler : public QXmlDefaultHandler {
  6. public:
  7.     bool startElement(const QString &namespaceURI,
  8.                      const QString &localName,
  9.                      const QString &qName,
  10.                      const QXmlAttributes &attributes) override {
  11.         qDebug() << "开始元素:" << qName;
  12.         for (int i = 0; i < attributes.count(); ++i) {
  13.             qDebug() << "  属性:" << attributes.qName(i)
  14.                     << "=" << attributes.value(i);
  15.         }
  16.         return true;
  17.     }
  18.    
  19.     bool endElement(const QString &namespaceURI,
  20.                    const QString &localName,
  21.                    const QString &qName) override {
  22.         qDebug() << "结束元素:" << qName;
  23.         return true;
  24.     }
  25.    
  26.     bool characters(const QString &ch) override {
  27.         QString text = ch.trimmed();
  28.         if (!text.isEmpty()) {
  29.             qDebug() << "文本内容:" << text;
  30.         }
  31.         return true;
  32.     }
  33.    
  34.     bool fatalError(const QXmlParseException &exception) override {
  35.         qDebug() << "XML 解析错误:" << exception.message();
  36.         return false;
  37.     }
  38. };
  39. void parseXmlWithSax(const QString &filePath) {
  40.     QFile file(filePath);
  41.     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  42.         qDebug() << "无法打开文件:" << filePath;
  43.         return;
  44.     }
  45.    
  46.     QXmlSimpleReader reader;
  47.     MyXmlHandler handler;
  48.     reader.setContentHandler(&handler);
  49.     reader.setErrorHandler(&handler);
  50.    
  51.     QXmlInputSource source(&file);
  52.     if (!reader.parse(&source)) {
  53.         qDebug() << "解析失败";
  54.     }
  55.    
  56.     file.close();
  57. }
  58. // 使用示例
  59. int main() {
  60.     parseXmlWithSax("example.xml");
  61.     return 0;
  62. }
复制代码
总结


  • QXmlStreamReader - 流式剖析器,内存效率高,适合大文件
  • QDomDocument - DOM 剖析器,适合小文件,便于随机访问和修改
  • SAX 剖析器 - 事件驱动模型,适合只需读取不需要修改的环境
  • 对于 Qt UI 文件,可以使用上述恣意方法剖析
选择发起:


  • 大文件或只需顺序读取 → QXmlStreamReader
  • 需要频繁修改或随机访问 → QDomDocument
  • 特别需求或性能关键 → SAX 剖析器

  1. from PyQt5.QtCore import QFile, QIODevice, QXmlStreamReader
  2. def parse_xml_with_stream(file_path):
  3.     file = QFile(file_path)
  4.     if not file.open(QIODevice.ReadOnly | QIODevice.Text):
  5.         print(f"无法打开文件: {file_path}")
  6.         return
  7.     xml = QXmlStreamReader(file)
  8.    
  9.     while not xml.atEnd():
  10.         xml.readNext()
  11.         
  12.         if xml.isStartElement():
  13.             print(f"开始元素: {xml.name()}")
  14.             # 打印所有属性
  15.             for attr in xml.attributes():
  16.                 print(f"  属性: {attr.name()} = {attr.value()}")
  17.                
  18.         elif xml.isEndElement():
  19.             print(f"结束元素: {xml.name()}")
  20.             
  21.         elif xml.isCharacters() and not xml.isWhitespace():
  22.             print(f"文本内容: {xml.text().strip()}")
  23.    
  24.     if xml.hasError():
  25.         print(f"XML 解析错误: {xml.errorString()}")
  26.    
  27.     file.close()
  28. if __name__ == "__main__":
  29.         # 替换为你的 XML 文件路径
  30.         xml_file_path = r"D:\shawei\temp\jpbalance\temp\TaskTemplates\Shock Pulse.xml"
  31.         parse_xml_with_stream(xml_file_path)
复制代码
  1. import xml.etree.ElementTree as ET
  2. def parse_xml_with_et(file_path):
  3.     try:
  4.         tree = ET.parse(file_path)
  5.         root = tree.getroot()
  6.         
  7.         # 命名空间处理
  8.         ns = {'cm': 'http://www.pruftechnik.com/cm'}
  9.         
  10.         print("=== 任务模板 ===")
  11.         print(f"版本: {root.get('version')}")
  12.         print(f"任务ID: {root.get('task_id')}")
  13.         print(f"名称: {root.get('name')}")
  14.         print(f"来源: {root.get('source')}")
  15.         
  16.         meas_setup = root.find('cm:meas_setup', ns)
  17.         print("\n=== 测量设置 ===")
  18.         print(f"类型: {meas_setup.get('kind')}")
  19.         
  20.         spectrum = meas_setup.find('cm:spectrum', ns)
  21.         print("\n=== 频谱配置 ===")
  22.         print(f"名称: {spectrum.get('name')}")
  23.         print(f"资源ID: {spectrum.get('res_id')}")
  24.         print(f"量值: {spectrum.get('quant')}")
  25.         print(f"线数: {spectrum.get('lines')}")
  26.         print(f"窗函数: {spectrum.get('window')}")
  27.         
  28.         time_waveform = spectrum.find('cm:time_waveform_config', ns)
  29.         print("\n=== 时域波形配置 ===")
  30.         print(f"名称: {time_waveform.get('name')}")
  31.         print(f"资源ID: {time_waveform.get('res_id')}")
  32.         print(f"量值: {time_waveform.get('quant')}")
  33.         
  34.         average = spectrum.find('cm:average', ns)
  35.         print("\n=== 平均设置 ===")
  36.         print(f"平均次数: {average.get('num')}")
  37.         print(f"重叠率: {average.get('overlap')}%")
  38.         print(f"因子: {average.get('factor')}")
  39.         print(f"类型: {average.get('type')}")
  40.         
  41.         freq_spectrum = spectrum.find('cm:freq_spectrum', ns)
  42.         print("\n=== 频谱范围 ===")
  43.         print(f"最大频率: {freq_spectrum.get('max')}Hz")
  44.         print(f"最大类型: {freq_spectrum.get('max_type')}")
  45.         print(f"最小频率: {freq_spectrum.get('min')}Hz")
  46.         
  47.     except ET.ParseError as e:
  48.         print(f"XML 解析错误: {e}")
  49.     except Exception as e:
  50.         print(f"发生错误: {e}")
  51. if __name__ == "__main__":
  52.     xml_file_path = r"D:\shawei\temp\jpbalance\temp\TaskTemplates\Shock Pulse.xml"
  53.     parse_xml_with_et(xml_file_path)
复制代码

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <task_template xmlns="http://www.xxxx.com/cm" version="4.0.0" task_id="00000000-0000-0000-0000-000000000003" name="Spec (a) 10Hz - 12800Hz" source="factory">
  3.         <meas_setup kind="trending_spectrum_amplitude">
  4.                 <spectrum name="Spectrum Velocity" res_id="00000000-0000-0000-0000-000000000002" quant="acc" lines="51200" window="hanning">
  5.                         <time_waveform_config name="Time Waveform Velocity" res_id="00000000-0000-0000-0000-000000000001" quant="acc"/>
  6.                         <average num="3" overlap="60" factor="0.5" type="lin"/>
  7.                         <freq_spectrum max="12800" max_type="time_based" min="10"/>
  8.                 </spectrum>
  9.         </meas_setup>
  10. </task_template>
复制代码
  1. #include <QCoreApplication>
  2. #include <QFile>
  3. #include <QXmlStreamReader>
  4. #include <QDebug>
  5. void parseTaskTemplateXml(const QString &filePath) {
  6.     QFile file(filePath);
  7.     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  8.         qDebug() << "无法打开文件:" << filePath;
  9.         return;
  10.     }
  11.     QXmlStreamReader xml(&file);
  12.    
  13.     while (!xml.atEnd() && !xml.hasError()) {
  14.         xml.readNext();
  15.         
  16.         if (xml.isStartElement()) {
  17.             QString elementName = xml.name().toString();
  18.             
  19.             if (elementName == "task_template") {
  20.                 qDebug() << "=== 任务模板 ===";
  21.                 qDebug() << "命名空间:" << xml.namespaceUri();
  22.                 qDebug() << "版本:" << xml.attributes().value("version").toString();
  23.                 qDebug() << "任务ID:" << xml.attributes().value("task_id").toString();
  24.                 qDebug() << "名称:" << xml.attributes().value("name").toString();
  25.                 qDebug() << "来源:" << xml.attributes().value("source").toString();
  26.             }
  27.             else if (elementName == "meas_setup") {
  28.                 qDebug() << "\n=== 测量设置 ===";
  29.                 qDebug() << "类型:" << xml.attributes().value("kind").toString();
  30.             }
  31.             else if (elementName == "spectrum") {
  32.                 qDebug() << "\n=== 频谱配置 ===";
  33.                 qDebug() << "名称:" << xml.attributes().value("name").toString();
  34.                 qDebug() << "资源ID:" << xml.attributes().value("res_id").toString();
  35.                 qDebug() << "量值:" << xml.attributes().value("quant").toString();
  36.                 qDebug() << "线数:" << xml.attributes().value("lines").toString();
  37.                 qDebug() << "窗函数:" << xml.attributes().value("window").toString();
  38.             }
  39.             else if (elementName == "time_waveform_config") {
  40.                 qDebug() << "\n=== 时域波形配置 ===";
  41.                 qDebug() << "名称:" << xml.attributes().value("name").toString();
  42.                 qDebug() << "资源ID:" << xml.attributes().value("res_id").toString();
  43.                 qDebug() << "量值:" << xml.attributes().value("quant").toString();
  44.             }
  45.             else if (elementName == "average") {
  46.                 qDebug() << "\n=== 平均设置 ===";
  47.                 qDebug() << "平均次数:" << xml.attributes().value("num").toString();
  48.                 qDebug() << "重叠率:" << xml.attributes().value("overlap").toString() << "%";
  49.                 qDebug() << "因子:" << xml.attributes().value("factor").toString();
  50.                 qDebug() << "类型:" << xml.attributes().value("type").toString();
  51.             }
  52.             else if (elementName == "freq_spectrum") {
  53.                 qDebug() << "\n=== 频谱范围 ===";
  54.                 qDebug() << "最大频率:" << xml.attributes().value("max").toString() << "Hz";
  55.                 qDebug() << "最大类型:" << xml.attributes().value("max_type").toString();
  56.                 qDebug() << "最小频率:" << xml.attributes().value("min").toString() << "Hz";
  57.             }
  58.         }
  59.     }
  60.    
  61.     if (xml.hasError()) {
  62.         qDebug() << "XML 解析错误:" << xml.errorString();
  63.     }
  64.    
  65.     file.close();
  66. }
  67. int main(int argc, char *argv[]) {
  68.     QCoreApplication a(argc, argv);
  69.    
  70.     parseTaskTemplateXml("task_template.xml");
  71.    
  72.     return a.exec();
  73. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表