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

如何使用VTD从符合条件的School节点提取指定类型Branch节点?

VTD-XML 提取指定Branch节点的实现方案

需要从XML中筛选出ScId以RC开头的School节点,再从这些节点里提取Type为Residential的Branch节点并创建对应Branch对象。现有代码无法正确定位目标Branch节点,以下是修正后的实现方案。

原始XML数据

<?xml version="1.0" encoding="ISO-8859-1"?>
<SchoolData>
<School>
<ScId>SC101-91</ScId>
    <Location>
      <Branch>
        <BranchId>Br-111</BranchId>
        <Type>Residential</Type>
        <RealType>Residential</RealType>
      </Branch>
      <Branch>
        <BranchId>BR-222</BranchId>
        <Type>Daycare</Type>
        <RealType>Daycare</RealType>
      </Branch>
      <Branch>
        <BranchId>Br-333</BranchId>
        <Type>Unknown</Type>
        <RealType>Unknown</RealType>
      </Branch>
    </Location>
</School>

<School>
<ScId>RC101-92</ScId>
    <Location>
      <Branch>
        <BranchId>Br-111</BranchId>
        <Type>Residential</Type>
        <RealType>Residential</RealType>
      </Branch>
      <Branch>
        <BranchId>BR-222</BranchId>
        <Type>Daycare</Type>
        <RealType>Daycare</RealType>
      </Branch>
      <Branch>
        <BranchId>Br-333</BranchId>
        <Type>Unknown</Type>
        <RealType>Unknown</RealType>
      </Branch>
    </Location>
</School>
</SchoolData>

现有代码的问题

  • 子XPath路径错误:多了冗余斜杠,且重复根路径的School筛选逻辑,未使用相对路径定位当前School节点下的Branch
  • 未遍历找到的Branch节点,也没有提取节点内的字段值并赋值给Branch对象

修正后的完整实现代码

public static void main(String[] args) throws XPathParseExceptionHuge, XPathEvalExceptionHuge, NavExceptionHuge {
    String xmlPath = "config/school.xml";
    
    // 初始化VTDGenHuge并解析XML文件
    VTDGenHuge vg = new VTDGenHuge();
    System.out.println("Parsing XML file...");
    vg.parseFile(xmlPath, true, VTDGenHuge.MEM_MAPPED);
    VTDNavHuge vn = vg.getNav();

    // 第一个AutoPilot:筛选ScId以RC开头的School节点
    AutoPilotHuge schoolAp = new AutoPilotHuge(vn);
    schoolAp.selectXPath("/*/School[starts-with(ScId,'RC')]");

    // 第二个AutoPilot:基于当前School节点,筛选Type为Residential的Branch(使用相对路径)
    AutoPilotHuge branchAp = new AutoPilotHuge(vn);
    branchAp.selectXPath("Location/Branch[Type='Residential']");

    // 遍历所有符合条件的School节点
    while (schoolAp.evalXPath() != -1) {
        System.out.println("Processing School with RC-prefixed ScId");
        
        // 遍历当前School下的目标Branch节点
        while (branchAp.evalXPath() != -1) {
            Branch branch = new Branch();
            
            // 提取BranchId字段值
            if (vn.toElement(VTDNavHuge.FIRST_CHILD, "BranchId")) {
                branch.setBranchId(vn.toNormalizedString(vn.getText()));
                vn.toElement(VTDNavHuge.PARENT); // 回到Branch父节点
            }
            
            // 提取Type字段值
            if (vn.toElement(VTDNavHuge.FIRST_CHILD, "Type")) {
                branch.setType(vn.toNormalizedString(vn.getText()));
                vn.toElement(VTDNavHuge.PARENT); // 回到Branch父节点
            }
            
            // 提取RealType字段值
            if (vn.toElement(VTDNavHuge.FIRST_CHILD, "RealType")) {
                branch.setRealType(vn.toNormalizedString(vn.getText()));
                vn.toElement(VTDNavHuge.PARENT); // 回到Branch父节点
            }
            
            // 可在此添加Branch对象的后续处理逻辑(如存入集合)
            System.out.println("Created Branch: " + branch.getBranchId() + ", Type: " + branch.getType());
        }
        
        // 重置Branch的AutoPilot,确保下一个School节点的遍历不受影响
        branchAp.resetXPath();
    }
}

// 假设的Branch实体类
class Branch {
    private String branchId;
    private String type;
    private String realType;

    // Getter和Setter方法
    public String getBranchId() { return branchId; }
    public void setBranchId(String branchId) { this.branchId = branchId; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
    public String getRealType() { return realType; }
    public void setRealType(String realType) { this.realType = realType; }
}

关键实现要点

  • 相对路径XPath:Location/Branch[Type='Residential'] 直接基于当前选中的School节点定位,避免全局重复查找
  • 双AutoPilot分工:一个负责筛选目标School,另一个负责在当前School下筛选目标Branch,逻辑清晰高效
  • 节点导航处理:使用vn.toElement()在父子节点间切换,vn.toNormalizedString()处理文本中的空白字符
  • AutoPilot重置:处理完一个School节点后,重置Branch的AutoPilot,保证下一轮遍历的正确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:16:20