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

RestAPI新手求助:Java解析Rest XML响应并提取特定实体

在Java中解析Rest XML响应提取多个值的方案

嘿,作为经常和Java XML解析打交道的开发者,我来帮你搞定这个问题!你需要从Rest API返回的XML响应里提取所有<objectId>标签的内容(比如<objectId>virtualwire-3560</objectId>这类),而且可能有多个,对吧?下面给你几种实用的方案,按需选择就行:

方法一:使用DOM解析

DOM会把整个XML加载到内存中,适合小到中等规模的XML响应,操作起来直观易懂,很适合你的场景。

实现步骤&代码示例:

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import java.io.StringReader;

public class XmlObjectIdExtractor {
    public static void main(String[] args) {
        // 替换成你实际从Rest API获取的XML响应字符串
        String xmlResponse = "<virtualWires><dataPage><pagingInfo><pageSize>10</pageSize><startIndex>0</startIndex><totalCount>4660</totalCount><sortOrderAscending>true</sortOrderAscending></pagingInfo><virtualWires><objectId>virtualwire-3560</objectId><objectId>virtualwire-3561</objectId></virtualWires></dataPage></virtualWires>";

        try {
            // 初始化DOM解析器
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new StringReader(xmlResponse));

            // 使用XPath查询所有<objectId>节点
            XPath xpath = XPathFactory.newInstance().newXPath();
            NodeList objectIdNodes = (NodeList) xpath.evaluate("//objectId", doc, javax.xml.xpath.XPathConstants.NODESET);

            // 遍历节点提取内容
            for (int i = 0; i < objectIdNodes.getLength(); i++) {
                String objectId = objectIdNodes.item(i).getTextContent().trim();
                System.out.println("提取到的ObjectId: " + objectId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方法二:使用SAX解析

如果你的XML响应特别大(比如包含上万条数据),DOM会占用太多内存,这时候SAX解析是更好的选择——它是流式解析,逐行读取XML,遇到目标标签时才提取内容,内存占用极低。

实现步骤&代码示例:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.StringReader;

public class SaxObjectIdExtractor {
    public static void main(String[] args) {
        String xmlResponse = "<virtualWires><dataPage><pagingInfo><pageSize>10</pageSize><startIndex>0</startIndex><totalCount>4660</totalCount><sortOrderAscending>true</sortOrderAscending></pagingInfo><virtualWires><objectId>virtualwire-3560</objectId><objectId>virtualwire-3561</objectId></virtualWires></dataPage></virtualWires>";

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            // 自定义SAX处理器,监听<objectId>标签
            DefaultHandler handler = new DefaultHandler() {
                private boolean isObjectIdTag = false;

                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                    // 遇到<objectId>标签时标记状态
                    if (qName.equalsIgnoreCase("objectId")) {
                        isObjectIdTag = true;
                    }
                }

                @Override
                public void characters(char ch[], int start, int length) throws SAXException {
                    // 如果当前是<objectId>标签内的内容,提取并输出
                    if (isObjectIdTag) {
                        String objectId = new String(ch, start, length).trim();
                        System.out.println("提取到的ObjectId: " + objectId);
                        isObjectIdTag = false; // 重置状态,避免重复读取
                    }
                }
            };

            saxParser.parse(new StringReader(xmlResponse), handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方法三:使用JAXB(XML对象绑定)

如果可以提前定义对应XML结构的Java实体类,JAXB会让解析变得异常优雅——它自动把XML映射成Java对象,你直接调用getter方法就能拿到数据,代码可读性极高。

第一步:定义对应XML结构的Java实体类

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "virtualWires")
public class VirtualWiresResponse {
    private DataPage dataPage;

    @XmlElement(name = "dataPage")
    public DataPage getDataPage() {
        return dataPage;
    }

    public void setDataPage(DataPage dataPage) {
        this.dataPage = dataPage;
    }

    // 内部类对应dataPage节点
    public static class DataPage {
        private PagingInfo pagingInfo;
        private List<VirtualWire> virtualWires;

        @XmlElement(name = "pagingInfo")
        public PagingInfo getPagingInfo() {
            return pagingInfo;
        }

        public void setPagingInfo(PagingInfo pagingInfo) {
            this.pagingInfo = pagingInfo;
        }

        @XmlElement(name = "virtualWires")
        public List<VirtualWire> getVirtualWires() {
            return virtualWires;
        }

        public void setVirtualWires(List<VirtualWire> virtualWires) {
            this.virtualWires = virtualWires;
        }
    }

    // 内部类对应pagingInfo节点
    public static class PagingInfo {
        private int pageSize;
        private int startIndex;
        private int totalCount;
        private boolean sortOrderAscending;

        @XmlElement(name = "pageSize")
        public int getPageSize() { return pageSize; }
        public void setPageSize(int pageSize) { this.pageSize = pageSize; }

        @XmlElement(name = "startIndex")
        public int getStartIndex() { return startIndex; }
        public void setStartIndex(int startIndex) { this.startIndex = startIndex; }

        @XmlElement(name = "totalCount")
        public int getTotalCount() { return totalCount; }
        public void setTotalCount(int totalCount) { this.totalCount = totalCount; }

        @XmlElement(name = "sortOrderAscending")
        public boolean isSortOrderAscending() { return sortOrderAscending; }
        public void setSortOrderAscending(boolean sortOrderAscending) { this.sortOrderAscending = sortOrderAscending; }
    }

    // 内部类对应单个virtualWire节点
    public static class VirtualWire {
        private String objectId;

        @XmlElement(name = "objectId")
        public String getObjectId() {
            return objectId;
        }

        public void setObjectId(String objectId) {
            this.objectId = objectId;
        }
    }
}

第二步:使用JAXB解析XML并提取数据

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;

public class JaxbObjectIdExtractor {
    public static void main(String[] args) {
        String xmlResponse = "<virtualWires><dataPage><pagingInfo><pageSize>10</pageSize><startIndex>0</startIndex><totalCount>4660</totalCount><sortOrderAscending>true</sortOrderAscending></pagingInfo><virtualWires><objectId>virtualwire-3560</objectId><objectId>virtualwire-3561</objectId></virtualWires></dataPage></virtualWires>";

        try {
            // 初始化JAXB上下文
            JAXBContext jaxbContext = JAXBContext.newInstance(VirtualWiresResponse.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            // 将XML字符串解析为Java对象
            VirtualWiresResponse response = (VirtualWiresResponse) unmarshaller.unmarshal(new StringReader(xmlResponse));

            // 遍历提取所有objectId
            for (VirtualWiresResponse.VirtualWire wire : response.getDataPage().getVirtualWires()) {
                System.out.println("提取到的ObjectId: " + wire.getObjectId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方案选择建议

  • 如果XML响应数据量小,优先选DOM或者JAXB,代码简单易维护;
  • 如果是超大XML响应,选SAX,避免内存溢出问题;
  • 如果后续需要频繁操作XML中的其他数据,JAXB是最优雅的选择,因为它把XML转换成了强类型的Java对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:27:47