You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为非有效XML文件生成闭合节点并按规则补全<sec>标签?

Hey there! Let's break down your two problems step by step—fixing unclosed XML nodes and adding hierarchical closing <sec> tags based on their id attributes.


1. Generating Closing Nodes for Invalid XML

Strict XML parsers will reject files with unclosed tags outright, so your first move is to use a tolerant parser that can recover and fix incomplete structures. Here's a practical approach using Python's lxml library, which has built-in recovery capabilities:

Example Code

from lxml import etree

# Load your invalid XML file
with open("invalid.xml", "r") as f:
    invalid_xml = f.read()

# Parse with recovery mode enabled
parser = etree.XMLParser(recover=True)
tree = etree.fromstring(invalid_xml.encode(), parser=parser)

# Convert back to well-formed XML
well_formed_xml = etree.tostring(tree, encoding="unicode", pretty_print=True)

# Save the result
with open("fixed.xml", "w") as f:
    f.write(well_formed_xml)

This will automatically add missing closing tags for most basic cases. For more edge cases (like malformed attribute values), you might need to pre-process the text to clean up obvious errors first.


2. Adding Closing <sec> Tags Based on ID Hierarchy

For your specific requirement of inserting </sec> tags before subsequent <sec> nodes based on the id hierarchy, here's a targeted solution. The core logic revolves around tracking the depth of each <sec> (from its dot-separated id) and calculating how many parent levels need to be closed when moving to a new <sec>.

Key Rules

Each id's depth is the number of dot-separated segments:

  • id="1" → depth 1
  • id="1.1" → depth 2
  • id="2.1.3" → depth 3

When processing a new <sec>:

  1. Compare its depth to the previous <sec>'s depth.
  2. If the new depth is less than the previous: insert (previous_depth - new_depth) closing tags.
  3. If the new depth equals the previous: insert 1 closing tag (close the sibling).
  4. If the new depth is greater: no closing tags needed (it's a child of the previous <sec>).
  5. Don't forget to add closing tags for all remaining open <sec> nodes at the end of the file.

Example Input

<sec id="1">
<sec id="1.1">
<sec id="1.2">
<sec id="2">
<sec id="2.1">
<sec id="2.1.1">
<sec id="3">

Expected Output

<sec id="1">
<sec id="1.1">
</sec>
<sec id="1.2">
</sec>
</sec>
<sec id="2">
<sec id="2.1">
<sec id="2.1.1">
</sec>
</sec>
</sec>
<sec id="3">
</sec>

Implementation Code (Python)

def fix_sec_closing_tags(input_path, output_path):
    with open(input_path, "r") as f:
        lines = [line.strip() for line in f if line.strip()]
    
    output = []
    previous_depth = 0
    
    for line in lines:
        if line.startswith("<sec id="):
            # Calculate current depth from id
            id_str = line.split('id="')[1].split('"')[0]
            current_depth = len(id_str.split("."))
            
            # Add closing tags based on depth difference
            if previous_depth > 0:
                diff = previous_depth - current_depth
                if diff >= 0:
                    # Add (diff + 1) closing tags if same depth, or diff if new is shallower
                    close_count = diff + 1 if current_depth == previous_depth else diff
                    output.extend(["</sec>"] * close_count)
            
            output.append(line)
            previous_depth = current_depth
    
    # Add closing tags for remaining open sec nodes
    output.extend(["</sec>"] * previous_depth)
    
    # Write the result with proper indentation
    with open(output_path, "w") as f:
        indent_level = 0
        for line in output:
            if line.startswith("</sec>"):
                indent_level -= 1
            f.write("  " * indent_level + line + "\n")
            if line.startswith("<sec id="):
                indent_level += 1

# Usage
fix_sec_closing_tags("input.xml", "output.xml")

内容的提问来源于stack exchange,提问作者Don_B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:36:55