You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android下基于Element解析XML文件的代码修改求助

从基于Attribute的XML解析切换到Element解析的修改指南

嘿,我明白你现在的困惑——之前用属性解析XML跑得好好的,现在要改成读取子元素,不知道从哪下手对吧?别担心,咱们针对你的XML结构一步步来拆解修改点:

首先得明确两种解析方式的核心区别:

  • 旧方式(Attribute):你之前读的是元素的属性值,比如 <Job JobNo="123456"> 这种结构,用 getAttribute("JobNo") 直接拿值。
  • 新方式(Element):现在你的XML是子元素承载数据,比如 <Job><JobNo>123456</JobNo></Job>,需要先定位到子元素,再读取它的文本内容。

核心修改步骤(以Android常用的DOM解析为例)

假设你之前的属性解析代码大概是这样:

// 旧的基于Attribute的解析代码
Document doc = 你的XML文档解析对象;
NodeList jobNodes = doc.getElementsByTagName("Job");
for (int i = 0; i < jobNodes.getLength(); i++) {
    Element jobElement = (Element) jobNodes.item(i);
    String jobNo = jobElement.getAttribute("JobNo");
    String jobType = jobElement.getAttribute("JobType");
    // ... 其他属性读取逻辑
}

现在改成Element解析,只需要调整内层数据读取的逻辑,外层获取<Job>节点的代码完全不用动!具体修改如下:

// 新的基于Element的解析代码
Document doc = 你的XML文档解析对象; // 这部分和之前完全一致,不用改
NodeList jobNodes = doc.getElementsByTagName("Job"); // 这部分也不用改,还是获取所有Job节点

for (int i = 0; i < jobNodes.getLength(); i++) {
    Element jobElement = (Element) jobNodes.item(i);
    
    // 读取JobNo子元素的文本(核心修改点)
    String jobNo = getChildElementText(jobElement, "JobNo");
    // 读取JobType子元素的文本
    String jobType = getChildElementText(jobElement, "JobType");
    // 读取Customer子元素的文本
    String customer = getChildElementText(jobElement, "Customer");
    // ... 其他字段都按这个方式处理
}

// 封装一个工具方法,避免重复写相同的查找逻辑
private String getChildElementText(Element parentElement, String tagName) {
    NodeList childNodes = parentElement.getElementsByTagName(tagName);
    if (childNodes.getLength() > 0) {
        Element childElement = (Element) childNodes.item(0);
        return childElement.getTextContent().trim(); // 去掉文本前后的空白字符
    }
    return ""; // 如果子元素不存在,返回空字符串避免空指针
}

关键疑问解答:需要重复调用getElementsByTagName吗?

完全不需要对整个文档重复调用!你只需要针对当前的<Job>元素调用getElementsByTagName(),这样只会查找这个Job节点下的子元素,既高效又不会拿到其他Job的内容。

如果用SAX解析怎么办?

要是你之前用的是SAX解析,修改逻辑也类似——从“读取属性”改成“收集子元素的文本内容”,示例代码如下:

public class JobSAXHandler extends DefaultHandler {
    private Job currentJob;
    private StringBuilder currentText;
    private List<Job> jobList;

    @Override
    public void startDocument() throws SAXException {
        jobList = new ArrayList<>();
        currentText = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        currentText.setLength(0); // 每次进入新元素前清空文本缓存
        if ("Job".equals(qName)) {
            currentJob = new Job(); // 创建新的Job对象
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        currentText.append(ch, start, length); // 收集当前元素的文本内容
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (currentJob == null) return;
        
        switch (qName) {
            case "JobNo":
                currentJob.setJobNo(currentText.toString().trim());
                break;
            case "JobType":
                currentJob.setJobType(currentText.toString().trim());
                break;
            case "Customer":
                currentJob.setCustomer(currentText.toString().trim());
                break;
            // ... 其他字段依次添加case
            case "Job":
                jobList.add(currentJob);
                currentJob = null;
                break;
        }
    }

    public List<Job> getJobList() {
        return jobList;
    }
}

总结一下修改核心

  1. getAttribute("XXX")的调用,替换成获取对应子元素并读取getTextContent()
  2. 针对单个<Job>元素查找子元素,而非整个文档
  3. 封装工具方法/统一处理逻辑,减少重复代码
  4. SAX解析则调整元素生命周期的处理逻辑,从读属性改成收集文本

这样修改后,就能完美适配你现在的XML结构啦!

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

火山引擎 最新活动