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

如何在JDOM2中为<start>与<stop>间元素创建最高层级XML父元素

JDOM2中为与间的元素创建最高层级父节点

需求:在JDOM2结构里,给位于<start>和<stop>两个边界元素之间的所有元素,创建尽可能最高层级的新XML父元素(示例中父元素名为<added>),<start>和<stop>可以放在任意位置。

简化示例

输入XML

<root>
    <a>
        <ax>
            <start></start>
        </ax>
        <ay></ay>
        <az></az>
    </a>
    <b>
       <bx></bx>
    </b>
    <c>
        <cx></cx>
        <cy></cy>
        <cz>
            <cza></cza>
            <czb>
                <stop></stop>
            </czb>
        </cz>
    </c>
</root>

输出XML

<root>
    <a>
        <ax>
            <start></start>
        </ax>
        <added>
            <ay></ay>
            <az></az>
        </added>
    </a>
    <added>
        <b>
            <bx></bx>
        </b>
    </added>
    <c>
        <added>
            <cx></cx>
            <cy></cy>
        </added>
        <cz>
            <added>
                <cza></cza>
            </added>
            <czb>
                <stop></stop>
            </czb>
        </cz>
    </c>
</root>

实现方案

核心思路

  1. 定位<start>和<stop>元素,筛选出两者之间的所有目标元素
  2. 对每个目标元素,向上查找不包含<start>或<stop>的最顶层父节点,这就是能包裹它的最高层级
  3. 在该父节点下创建<added>元素,把同一层级的目标元素都移动进去,避免重复创建父元素

JDOM2代码实现

import org.jdom2.*;
import org.jdom2.filter.Filters;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
import java.util.List;
import java.util.Optional;

public class WrapBetweenStartStop {
    public static void main(String[] args) throws JDOMException {
        // 这里假设你已经加载好XML文档到Document对象
        Document doc = getSampleDocument();

        XPathFactory xpf = XPathFactory.instance();
        // 找到start和stop元素
        Element start = xpf.compile("//start", Filters.element()).evaluateFirst(doc);
        Element stop = xpf.compile("//stop", Filters.element()).evaluateFirst(doc);

        if (start == null || stop == null) {
            System.out.println("未找到start或stop元素");
            return;
        }

        // 筛选出start之后、stop之前的所有元素(排除自身)
        List<Element> targetElements = xpf.compile(
                "//*[preceding::start and following::stop]", Filters.element())
                .evaluate(doc);

        // 遍历处理每个目标元素
        for (Element elem : targetElements) {
            Element highestParent = findHighestValidParent(elem, start, stop);
            // 检查当前父节点下是否已有added元素,没有则创建
            Element added = findOrCreateAddedElement(highestParent, elem);
            // 把元素移到added里
            elem.detach();
            added.addContent(elem);
        }

        // 输出处理后的XML
        XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
        try {
            outputter.output(doc, System.out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 找到不包含start/stop的最高层级父节点
    private static Element findHighestValidParent(Element elem, Element start, Element stop) {
        Element current = elem.getParentElement();
        Element lastValid = elem.getParentElement();
        while (current != null) {
            // 检查当前父节点是否包含start或stop
            boolean hasStart = current.getDescendants(Filters.element())
                    .anyMatch(e -> e.equals(start));
            boolean hasStop = current.getDescendants(Filters.element())
                    .anyMatch(e -> e.equals(stop));
            if (hasStart || hasStop) {
                break;
            }
            lastValid = current;
            current = current.getParentElement();
        }
        return lastValid;
    }

    // 在指定父节点下查找或创建added元素,插入到目标元素的原位置
    private static Element findOrCreateAddedElement(Element parent, Element target) {
        // 先找已有的added元素
        Optional<Element> existingAdded = parent.getChildren("added").stream().findFirst();
        if (existingAdded.isPresent()) {
            return existingAdded.get();
        }
        // 创建新的added元素,插入到目标元素原来的位置
        Element added = new Element("added");
        int index = parent.indexOf(target);
        parent.addContent(index, added);
        return added;
    }

    // 生成示例文档(仅用于测试)
    private static Document getSampleDocument() {
        Element root = new Element("root");
        Element a = new Element("a");
        Element ax = new Element("ax").addContent(new Element("start"));
        a.addContent(ax).addContent(new Element("ay")).addContent(new Element("az"));
        Element b = new Element("b").addContent(new Element("bx"));
        Element c = new Element("c");
        Element cz = new Element("cz").addContent(new Element("cza"));
        Element czb = new Element("czb").addContent(new Element("stop"));
        cz.addContent(czb);
        c.addContent(new Element("cx")).addContent(new Element("cy")).addContent(cz);
        root.addContent(a).addContent(b).addContent(c);
        return new Document(root);
    }
}

代码说明

  • findHighestValidParent:向上遍历父节点,直到遇到包含<start>或<stop>的节点,返回之前的最后一个有效父节点,保证包裹层级最高
  • findOrCreateAddedElement:避免在同一父节点下重复创建<added>元素,同时保持目标元素的原有顺序
  • XPath筛选:精准定位出<start>和<stop>之间的所有元素,确保只处理目标节点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:50:29