|
|
|
@ -37,32 +37,9 @@ class TemplateParserController extends BaseContentController {
@@ -37,32 +37,9 @@ class TemplateParserController extends BaseContentController {
|
|
|
|
|
|
|
|
|
|
void selectTreeNode(TemplateNode node) { |
|
|
|
|
_selectedNode = node; |
|
|
|
|
_templateItems = _generateTemplateItems(node); |
|
|
|
|
notifyListeners(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
List<TemplateItem> _generateTemplateItems(TemplateNode node) { |
|
|
|
|
// 实际项目中应从XML解析真实数据 |
|
|
|
|
return [ |
|
|
|
|
if (node.attributes != null) |
|
|
|
|
...node.attributes!.entries.map( |
|
|
|
|
(e) => TemplateItem( |
|
|
|
|
id: e.key.hashCode, |
|
|
|
|
content: '${node.name}.${e.key}', |
|
|
|
|
xPath: '${node.name}@${e.key}', |
|
|
|
|
value: e.value, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
if (node.text != null && node.text!.trim().isNotEmpty) |
|
|
|
|
TemplateItem( |
|
|
|
|
id: node.text.hashCode, |
|
|
|
|
content: node.text!, |
|
|
|
|
xPath: '${node.name}/text()', |
|
|
|
|
value: node.text!, |
|
|
|
|
), |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Future<void> _loadTemplateData() async { |
|
|
|
|
try { |
|
|
|
|
_errorMessage = null; |
|
|
|
@ -85,36 +62,62 @@ class TemplateParserController extends BaseContentController {
@@ -85,36 +62,62 @@ class TemplateParserController extends BaseContentController {
|
|
|
|
|
|
|
|
|
|
Future<void> _parseXmlContent(String xmlContent) async { |
|
|
|
|
final document = xml.XmlDocument.parse(xmlContent); |
|
|
|
|
Logger().debug('开始解析XML,根元素: ${document.rootElement.name}'); |
|
|
|
|
_treeNodes = _buildTreeNodes(document.rootElement, depth: 0); |
|
|
|
|
Logger().debug('解析完成,共生成 ${_treeNodes.length} 个顶级节点'); |
|
|
|
|
notifyListeners(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
List<TemplateNode> _buildTreeNodes(xml.XmlElement element, {required int depth}) { |
|
|
|
|
List<TemplateNode> _buildTreeNodes( |
|
|
|
|
xml.XmlElement element, { |
|
|
|
|
required int depth, |
|
|
|
|
int repreatCount = 1, |
|
|
|
|
}) { |
|
|
|
|
final node = TemplateNode( |
|
|
|
|
name: element.name.local, |
|
|
|
|
children: [], |
|
|
|
|
attributes: |
|
|
|
|
element.attributes.isNotEmpty |
|
|
|
|
? {for (var attr in element.attributes) attr.name.local: attr.value} |
|
|
|
|
: null, |
|
|
|
|
text: element.text.trim().isNotEmpty ? element.text : null, |
|
|
|
|
depth: depth, |
|
|
|
|
isExpanded: depth < 1, // 默认展开第一层 |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// 处理子元素 |
|
|
|
|
node.children.addAll( |
|
|
|
|
element.children.whereType<xml.XmlElement>().map( |
|
|
|
|
(e) => _buildTreeNodes(e, depth: depth + 1).first, |
|
|
|
|
), |
|
|
|
|
isExpanded: depth < 5, // 默认展开前两层 |
|
|
|
|
isRepeated: repreatCount > 1, |
|
|
|
|
repreatCount: repreatCount, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// 添加属性节点 |
|
|
|
|
// 添加当前元素的所有属性节点 |
|
|
|
|
if (element.attributes.isNotEmpty) { |
|
|
|
|
node.children.addAll( |
|
|
|
|
element.attributes.map((attr) => TemplateNode.attribute(attr.name.local, attr.value)), |
|
|
|
|
element.attributes.map( |
|
|
|
|
(attr) => TemplateNode( |
|
|
|
|
name: '@${attr.name.local}', |
|
|
|
|
children: [], |
|
|
|
|
depth: depth + 1, |
|
|
|
|
isAttribute: true, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 处理子元素节点(忽略文本节点) |
|
|
|
|
final childElements = element.children.whereType<xml.XmlElement>(); |
|
|
|
|
final groupedChildren = <String, List<xml.XmlElement>>{}; |
|
|
|
|
|
|
|
|
|
// 按元素名分组 |
|
|
|
|
for (var child in childElements) { |
|
|
|
|
groupedChildren.putIfAbsent(child.name.local, () => []).add(child); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 为每个唯一子元素创建节点 |
|
|
|
|
groupedChildren.forEach((name, elements) { |
|
|
|
|
if (elements.length == 1) { |
|
|
|
|
// 单一节点直接添加(包含其所有属性) |
|
|
|
|
node.children.addAll(_buildTreeNodes(elements.first, depth: depth + 1)); |
|
|
|
|
} else { |
|
|
|
|
// 多个相同节点需要合并 |
|
|
|
|
node.children.addAll( |
|
|
|
|
_buildTreeNodes(elements.first, depth: depth + 1, repreatCount: elements.length), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return [node]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|