Python文件解析与plan-feature-measure层级数据结构构建问询
解析层级配置文件并构建Python数据结构
需求说明
需要解析包含一个或多个plan的配置文件,层级关系为:
- 每个
plan下可包含多个feature feature支持嵌套子featurefeature下包含带有src信息的measure,src可能有多行内容
待解析文件示例:
plan HELLO feature A measure X : src = "Type ,Name" endmeasure //X measure Y : src = "Type ,Name" endmeasure //Y feature Aa measure AaX : src = "Type ,Name" "Type ,Name2" "Type ,Name3" endmeasure //AaX measure AaY : src = "Type ,Name" endmeasure //AaY feature Aab ..... endfeature // Aab endfeature //Aa endfeature // A feature B ...... endfeature //B endplan plan HOLA endplan //HOLA
目标数据结构层级:
plan (HELLO) ------------------------------ ↓ ↓ Feature A Feature B ---------------------------- ↓ ↓ ↓ ↓ ........ Measure X Measure Y Feature Aa ------------------------------ ↓ ↓ ↓ Measure AaX Measure AaY Feature Aab ↓ .......
现有代码问题分析
你提供的getplans函数存在以下关键问题,无法正确实现需求:
- 错误识别节点类型:把
measure X :当成叶子节点处理,但实际measure是容器节点,内部的src才是其属性 - 多行
src处理失效:仅能处理单行src值,无法收集示例中measure AaX的多行src内容 - 数据结构逻辑混乱:
stack_list复用机制错误,同一层级的多个measure会共享列表导致数据覆盖;用MEASURED_VAL存储属性,未关联到对应的measure节点 - 分割逻辑不严谨:对
line.split()的依赖未考虑边界情况,容易出现解析错误
优化解析方案
以下是更健壮的实现,能正确处理嵌套结构和多行src:
def parse_config(content): # 栈维护当前解析的节点层级,初始根节点存储所有plans stack = [{"plans": {}}] current_measure = None # 跟踪当前正在处理的measure,用于收集多行src for line in content.splitlines(): line = line.strip() if not line: continue # 跳过空行 # 处理结束标签:endplan/endfeature/endmeasure if line.startswith("end"): if current_measure: current_measure = None stack.pop() continue # 处理带冒号的容器节点(measure定义行,如measure X :) if line.endswith(":"): parts = line[:-1].split(maxsplit=1) if len(parts) != 2: continue collection, name = parts # 创建measure节点并加入父节点的measures集合 measure_node = {"name": name, "src": []} parent = stack[-1] parent.setdefault("measures", {})[name] = measure_node stack.append(measure_node) current_measure = measure_node continue # 处理不带冒号的容器节点(plan/feature定义行,如plan HELLO) if " " in line: parts = line.split(maxsplit=1) if len(parts) != 2: continue collection, name = parts node = {"name": name} parent = stack[-1] # 根据节点类型加入父节点对应集合 if collection == "plan": parent["plans"][name] = node else: parent.setdefault(f"{collection}s", {})[name] = node stack.append(node) continue # 处理属性行(如src = "Type ,Name") if "=" in line: key, value = line.split("=", 1) key = key.strip() value = value.strip().strip('"') if current_measure and key == "src": current_measure["src"].append(value) continue return stack[0]["plans"]
方案说明
- 栈结构管理层级:通过栈跟踪当前解析的节点,新容器节点入栈,结束标签触发出栈,清晰维护层级关系
- 多行
src收集:用current_measure变量跟踪当前measure,将多行src值统一存入列表 - 清晰的节点结构:每个节点包含
name字段,子节点按类型存入features/measures集合,measure的src属性明确存储 - 容错处理:跳过空行,处理分割异常情况,提升代码鲁棒性
测试验证
用示例内容调用函数后,会得到如下结构的字典(简化展示):
{ "HELLO": { "name": "HELLO", "features": { "A": { "name": "A", "measures": { "X": {"name": "X", "src": ["Type ,Name"]}, "Y": {"name": "Y", "src": ["Type ,Name"]} }, "features": { "Aa": { "name": "Aa", "measures": { "AaX": {"name": "AaX", "src": ["Type ,Name", "Type ,Name2", "Type ,Name3"]}, "AaY": {"name": "AaY", "src": ["Type ,Name"]} }, "features": {"Aab": {...}} } } }, "B": {...} } }, "HOLA": {"name": "HOLA"} }
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

