如何在Java中提取字符串格式XML中的特定值?
在Java中提取XML字符串的特定值
先整理你需要处理的核心XML内容(先剥离外层的<p><code>标签):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:services xmlns:ns2="http://www.3ds.com/enovia/e6wv2"> <ns2:serviceData> <ns2:statusCode>200</ns2:statusCode> <ns2:success>true</ns2:success> <ns2:csrf name="ENO_CSRF_TOKEN" value="JYOF-K5LS-INZM-15O3-4O00-VTBJ-R28O-YY2P"/> </ns2:serviceData> </ns2:services>
下面提供两种实用的提取方式:
方法一:使用原生DOM+XPath(无额外依赖)
直接用JDK自带API,无需引入第三方库。
代码示例
import org.w3c.dom.Document; import org.xml.sax.InputSource; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import java.io.StringReader; public class XmlExtractor { public static void main(String[] args) { // 原始输入字符串 String xmlStr = "<p><code><?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><ns2:services xmlns:ns2=\"http://www.3ds.com/enovia/e6wv2\"><ns2:serviceData><ns2:statusCode>200</ns2:statusCode><ns2:success>true</ns2:success><ns2:csrf name=\"ENO_CSRF_TOKEN\" value=\"JYOF-K5LS-INZM-15O3-4O00-VTBJ-R28O-YY2P\"/></ns2:serviceData></ns2:services></code></p>"; // 提取核心XML部分,剥离外层标签 String coreXml = xmlStr.substring(xmlStr.indexOf("<?xml"), xmlStr.indexOf("</ns2:services>") + "</ns2:services>".length()); try { // 初始化XPath并注册命名空间 XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(new javax.xml.namespace.NamespaceContext() { @Override public String getNamespaceURI(String prefix) { return "ns2".equals(prefix) ? "http://www.3ds.com/enovia/e6wv2" : javax.xml.XMLConstants.NULL_NS_URI; } @Override public String getPrefix(String namespaceURI) { return null; } @Override public java.util.Iterator<String> getPrefixes(String namespaceURI) { return null; } }); // 解析XML为Document对象 Document doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder() .parse(new InputSource(new StringReader(coreXml))); // 提取目标值 String statusCode = xpath.evaluate("/ns2:services/ns2:serviceData/ns2:statusCode", doc); String success = xpath.evaluate("/ns2:services/ns2:serviceData/ns2:success", doc); String csrfName = xpath.evaluate("/ns2:services/ns2:serviceData/ns2:csrf/@name", doc); String csrfValue = xpath.evaluate("/ns2:services/ns2:serviceData/ns2:csrf/@value", doc); // 输出结果 System.out.println("statusCode: " + statusCode); System.out.println("success: " + success); System.out.println("csrf name: " + csrfName); System.out.println("csrf value: " + csrfValue); } catch (Exception e) { e.printStackTrace(); } } }
关键说明
- 必须注册XML的命名空间,否则XPath无法识别带前缀的标签
- 先剥离外层的
<p><code>标签,避免解析时出现非XML结构的错误
方法二:使用Jackson XML(简洁高效,需引入依赖)
如果项目已使用Jackson,这种方式代码更简洁,无需手动操作DOM。
第一步:引入Maven依赖
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> <!-- 使用最新稳定版 --> </dependency>
第二步:编写实体类映射XML结构
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; @JacksonXmlRootElement(localName = "services", namespace = "http://www.3ds.com/enovia/e6wv2") public class Services { @JacksonXmlProperty(localName = "serviceData", namespace = "http://www.3ds.com/enovia/e6wv2") private ServiceData serviceData; // getter & setter public ServiceData getServiceData() { return serviceData; } public void setServiceData(ServiceData serviceData) { this.serviceData = serviceData; } public static class ServiceData { @JacksonXmlProperty(localName = "statusCode", namespace = "http://www.3ds.com/enovia/e6wv2") private String statusCode; @JacksonXmlProperty(localName = "success", namespace = "http://www.3ds.com/enovia/e6wv2") private String success; @JacksonXmlProperty(localName = "csrf", namespace = "http://www.3ds.com/enovia/e6wv2") private Csrf csrf; // getter & setter public String getStatusCode() { return statusCode; } public void setStatusCode(String statusCode) { this.statusCode = statusCode; } public String getSuccess() { return success; } public void setSuccess(String success) { this.success = success; } public Csrf getCsrf() { return csrf; } public void setCsrf(Csrf csrf) { this.csrf = csrf; } } public static class Csrf { @JacksonXmlProperty(isAttribute = true) private String name; @JacksonXmlProperty(isAttribute = true) private String value; // getter & setter public String getName() { return name; } public void setName(String name) { this.name = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }
第三步:解析XML并提取值
import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class JacksonXmlExtractor { public static void main(String[] args) { String xmlStr = "<p><code><?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><ns2:services xmlns:ns2=\"http://www.3ds.com/enovia/e6wv2\"><ns2:serviceData><ns2:statusCode>200</ns2:statusCode><ns2:success>true</ns2:success><ns2:csrf name=\"ENO_CSRF_TOKEN\" value=\"JYOF-K5LS-INZM-15O3-4O00-VTBJ-R28O-YY2P\"/></ns2:serviceData></ns2:services></code></p>"; String coreXml = xmlStr.substring(xmlStr.indexOf("<?xml"), xmlStr.indexOf("</ns2:services>") + "</ns2:services>".length()); try { XmlMapper xmlMapper = new XmlMapper(); Services services = xmlMapper.readValue(coreXml, Services.class); // 提取目标值 String statusCode = services.getServiceData().getStatusCode(); String success = services.getServiceData().getSuccess(); String csrfName = services.getServiceData().getCsrf().getName(); String csrfValue = services.getServiceData().getCsrf().getValue(); // 输出结果 System.out.println("statusCode: " + statusCode); System.out.println("success: " + success); System.out.println("csrf name: " + csrfName); System.out.println("csrf value: " + csrfValue); } catch (Exception e) { e.printStackTrace(); } } }
关键说明
- 实体类的命名空间、标签名必须和XML完全对应
@JacksonXmlProperty(isAttribute = true)用于标记XML属性(如csrf的name和value)
内容的提问来源于stack exchange,提问作者Praveen s
相关产品推荐
相关产品推荐

