2 changed files with 122 additions and 17 deletions
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
import 'dart:convert'; |
||||
import 'dart:io'; |
||||
import 'package:xml/xml.dart'; |
||||
|
||||
class FastXmlParser { |
||||
/// 批量解析XML文件根节点属性 |
||||
static Future<List<Map<String, String>>> batchParse( |
||||
List<String> filePaths, { |
||||
int maxFastParseBytes = 1024, |
||||
}) async { |
||||
return await Future.wait(filePaths.map((path) => _parseWithFallback(path, maxFastParseBytes))); |
||||
} |
||||
|
||||
static Future<Map<String, String>> parse(String filePath, {int maxFastParseBytes = 512}) async { |
||||
return _parseWithFallback(filePath, maxFastParseBytes); |
||||
} |
||||
|
||||
/// 带降级的解析流程 |
||||
static Future<Map<String, String>> _parseWithFallback(String path, int maxBytes) async { |
||||
try { |
||||
// 优先尝试快速解析 |
||||
return await _fastParseRootAttributes(path, maxBytes); |
||||
} catch (e) { |
||||
// 快速解析失败时降级到DOM解析 |
||||
return await _domParseRootAttributes(path); |
||||
} |
||||
} |
||||
|
||||
/// 快速解析方案(正则匹配) |
||||
static Future<Map<String, String>> _fastParseRootAttributes(String path, int maxBytes) async { |
||||
final file = File(path); |
||||
final raf = await file.open(); |
||||
try { |
||||
// 仅读取文件开头部分 |
||||
final buffer = await raf.read(maxBytes); |
||||
final content = utf8.decode(buffer); |
||||
|
||||
// 使用正则提取开始标签属性 |
||||
final startTag = RegExp( |
||||
r'(?:<\?xml[^?>]*\?>[\s\r\n]*)?<([^\s>]+)([^>]*)>', |
||||
caseSensitive: false, |
||||
).firstMatch(content); |
||||
if (startTag == null) throw Exception('No start tag found'); |
||||
|
||||
final attrs = _parseAttributes(startTag.group(2)!); |
||||
return _extractRequiredAttributes(attrs); |
||||
} finally { |
||||
await raf.close(); |
||||
} |
||||
} |
||||
|
||||
/// DOM解析降级方案 |
||||
static Future<Map<String, String>> _domParseRootAttributes(String path) async { |
||||
final content = await File(path).readAsString(); |
||||
final document = XmlDocument.parse(content); |
||||
final attrs = document.rootElement.attributes.fold<Map<String, String>>( |
||||
{}, |
||||
(map, attr) => map..[attr.name.qualified] = attr.value, |
||||
); |
||||
return _extractRequiredAttributes(attrs); |
||||
} |
||||
|
||||
/// 辅助方法:解析属性字符串 |
||||
static Map<String, String> _parseAttributes(String attrStr) { |
||||
return RegExp(r'(\w+)="([^"]*)"') |
||||
.allMatches(attrStr) |
||||
.fold<Map<String, String>>({}, (map, match) => map..[match.group(1)!] = match.group(2)!); |
||||
} |
||||
|
||||
/// 辅助方法:提取目标属性 |
||||
static Map<String, String> _extractRequiredAttributes(Map<String, String> attrs) { |
||||
return {'chineseName': attrs['chineseName'] ?? '', 'objectId': attrs['objectId'] ?? ''}; |
||||
} |
||||
} |
Loading…
Reference in new issue