java用xpath解析XML
获取值为空
public class XmlToObject {
public static void main(String[] args) throws Exception {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ID>NZL2014/AFFCO1/762648</ID>\n" +
"\t<SignatorySPSAuthentication>\n" +
"\t\t<IncludedSPSClause>\n" +
" <ID>1</ID>\n" +
" <Content languageID=\"en\">I hereby certify that the products:</Content>\n" +
" <Content languageID=\"zh\">本人在此证明该产品:</Content>\n" +
" </IncludedSPSClause>\n" +
"\t</SignatorySPSAuthentication>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
NzlSPSCertificateNamespaceContext namespaceContext = new NzlSPSCertificateNamespaceContext();
xpath.setNamespaceContext(namespaceContext);
//ns2:SPSCertificate/ns2:SPSExchangedDocument/default:ID
XPathExpression expr = xpath.compile(
"ns2:SPSCertificate/ns2:SPSExchangedDocument/default:SignatorySPSAuthentication/default:IncludedSPSClause\n" +
"[ID = '1']/default:Content[@languageID = 'zh']");
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println(node.getTextContent());
}
}
}
class NzlSPSCertificateNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns2".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:SPSCertificate:5";
} else if ("default".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
System.out.println(namespaceURI);
throw new UnsupportedOperationException();
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
xml结构是
<ns2:SPSCertificate xmlns:ns2="urn:un:unece:uncefact:data:standard:SPSCertificate:5" xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9">
<ns2:SPSExchangedDocument>
<ID>NZL2014/AFFCO1/762648</ID>
<SignatorySPSAuthentication>
<IncludedSPSClause>
<ID>1</ID>
<Content languageID="en">I hereby certify that the products:</Content>
<Content languageID="zh">本人在此证明该产品:</Content>
</IncludedSPSClause>
</SignatorySPSAuthentication>
</ns2:SPSExchangedDocument>
</ns2:SPSCertificate>
用xpath取出"ns2:SPSCertificate/ns2:SPSExchangedDocument/SignatorySPSAuthentication/IncludedSPSClause
[ID = '1']/Content[@languageID = 'zh']"
打印下document给我看看
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
如果有用的话,请采纳下!!!
我刚才跑了下你的代码,有问题,获取不到数据,document是null。我给你改了下。
public static void main(String[] args) throws Exception {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ID>NZL2014/AFFCO1/762648</ID>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
try {
// 创建DOM解析器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
// 创建DOM解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 将XML字符串解析为Document对象
Document document = builder.parse(new InputSource(new StringReader(xml)));
// 获取根元素
Element rootElement = document.getDocumentElement();
// 获取ns2:SPSExchangedDocument元素
Element spsExchangedDocumentElement = (Element) rootElement.getElementsByTagName("ns2:SPSExchangedDocument").item(0);
// 获取ID元素
Element idElement = (Element) spsExchangedDocumentElement.getElementsByTagName("ID").item(0);
// 获取ID元素的文本内容
String idValue = idElement.getTextContent();
System.out.println("ID参数的值是:" + idValue);
} catch (Exception e) {
e.printStackTrace();
}
}
输出结果:ID参数的值是:NZL2014/AFFCO1/762648
引用 皆我百晓生 小程序回复内容作答:
你的代码基本上是正确的,但由于使用了命名空间,所以在编写XPath表达式时需要小心处理。你可以尝试以下修改来获取正确的值:
public class XmlToObject {
public static void main(String[] args) throws Exception {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ID>NZL2014/AFFCO1/762648</ID>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(new NzlSPSCertificateNamespaceContext());
XPathExpression expr = xpath.compile(
"//ns2:SPSExchangedDocument/ID");
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println(node.getTextContent());
}
}
}
class NzlSPSCertificateNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns2".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:SPSCertificate:5";
} else if ("".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
if ("urn:un:unece:uncefact:data:standard:SPSCertificate:5".equals(namespaceURI)) {
return "ns2";
} else if ("urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9".equals(namespaceURI)) {
return "";
}
return null;
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
请注意,XPath表达式中的//
表示匹配任意深度的子节点,这样即使在命名空间的父节点上也能正常工作。这对于你的XML结构非常有用,因为它有多个命名空间级别。
通过以上修改,你应该能够正确获取到ID节点的文本内容。希望能对你有所帮助!
package com.vod.web.controller.system;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class XMLParser {
public static void main(String[] args) {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ID>NZL2014/AFFCO1/762648</ID>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
// 获取根元素
Element rootElement = document.getDocumentElement();
// 获取子元素
NodeList nodeList = rootElement.getElementsByTagName("ID");
if (nodeList.getLength() > 0) {
Node idNode = nodeList.item(0);
String id = idNode.getTextContent();
System.out.println("ID: " + id);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
下是稍作修改后的代码示例,应该可以正确获取到ID的值
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class XmlToObject {
public static void main(String[] args) throws Exception {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ID>NZL2014/AFFCO1/762648</ID>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
// 创建XPath对象
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(new NzlSPSCertificateNamespaceContext());
// 编译XPath表达式
XPathExpression expr = xpath.compile("/ns2:SPSCertificate/ns2:SPSExchangedDocument/ID");
// 解析XML文档
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
// 评估XPath表达式并获取节点列表
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
// 遍历节点列表并输出文本内容
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println(node.getTextContent());
}
}
}
class NzlSPSCertificateNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns2".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:SPSCertificate:5";
} else if ("".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
if ("urn:un:unece:uncefact:data:standard:SPSCertificate:5".equals(namespaceURI)) {
return "ns2";
} else if ("urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9".equals(namespaceURI)) {
return "";
}
return null;
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您的代码基本上是正确的,但是有一个小问题导致您无法获取到值。在使用XPath表达式时,您需要使用正确的命名空间前缀来匹配XML中的命名空间URI。
在您的代码中,您定义了NzlSPSCertificateNamespaceContext
类来处理命名空间。根据您提供的XML,命名空间URI urn:un:unece:uncefact:data:standard:SPSCertificate:5
被分配给了 ns2
前缀。然而,在XPath表达式中,您使用了 ns2:SPSCertificate
,而实际上应该是 ns2:SPSCertificate
。
请修改您的XPath表达式为 /ns2:SPSCertificate/ns2:SPSExchangedDocument/ns2:ID
,然后再次运行代码。这样您应该能够成功获取到 <ID>
元素的值。
以下是修改后的代码:
public class XmlToObject {
public static void main(String[] args) throws Exception {
String xml = "<ns2:SPSCertificate xmlns:ns2=\"urn:un:unece:uncefact:data:standard:SPSCertificate:5\" xmlns=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9\">\n" +
" <ns2:SPSExchangedDocument>\n" +
" <ns2:ID>NZL2014/AFFCO1/762648</ns2:ID>\n" +
" </ns2:SPSExchangedDocument>\n" +
"</ns2:SPSCertificate>";
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(new NzlSPSCertificateNamespaceContext());
XPathExpression expr = xpath.compile(
"/ns2:SPSCertificate/ns2:SPSExchangedDocument/ns2:ID");
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println(node.getTextContent());
}
}
}
class NzlSPSCertificateNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns2".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:SPSCertificate:5";
} else if ("".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
if ("urn:un:unece:uncefact:data:standard:SPSCertificate:5".equals(namespaceURI)) {
return "ns2";
} else if ("urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9".equals(namespaceURI)) {
return "";
}
return null;
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
运行代码后,您应该能够成功获取到 <ID>
元素的值 "NZL2014/AFFCO1/762648"
。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
java通过XPATH解析XML
package testXpath;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.NodeList;
public class TestXpathExample {
public static void main(String args[]) throws FileNotFoundException, TransformerException, XPathExpressionException{
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer transFormer = transFact.newTransformer();
DOMResult dom = new DOMResult();
transFormer.transform(new StreamSource(new FileInputStream(new File("test.xml"))), dom);
XPath xpath = XPathFactory.newInstance().newXPath();
@SuppressWarnings("serial")
Map<String,String> prefix2uri = new HashMap<String,String>(){{
put("foo","http://www.baidu.com");
put("bar","http://www.google.com");
}};
@SuppressWarnings("serial")
Map<String,String> uri2prefix = new HashMap<String,String>(){{
put("http://www.baidu.com","foo");
put("http://www.google.com","bar");
}};
xpath.setNamespaceContext(new NsSolver(prefix2uri,uri2prefix));
XPathExpression expression = xpath.compile("//player");
NodeList nodeList = (NodeList)expression.evaluate(dom.getNode(),XPathConstants.NODESET);
for(int i = 0; i < nodeList.getLength(); i++){
System.out.println(nodeList.item(i).getNodeName());
}
}
}
【以下回答由 GPT 生成】
问题出在getPrefix
方法上。根据XPath规范,getPrefix
方法应该返回指定命名空间的前缀。因此,需要修改NzlSPSCertificateNamespaceContext
类的getPrefix
方法,使其正确返回命名空间的前缀。
以下是修改后的代码:
class NzlSPSCertificateNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns2".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:SPSCertificate:5";
} else if ("".equals(prefix)) {
return "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9";
}
return null;
}
@Override
public String getPrefix(String namespaceURI) {
if ("urn:un:unece:uncefact:data:standard:SPSCertificate:5".equals(namespaceURI)) {
return "ns2";
} else if ("urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:9".equals(namespaceURI)) {
return "";
}
return null;
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
修改后的代码中,getPrefix
方法根据命名空间的URI返回对应的前缀。这样,XPath解析器就能正确解析带有命名空间的XPath表达式,从而正确获取节点的值。
你可以重新运行代码,应该能够正确获取节点 <ID>
的值。
【相关推荐】
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
结合GPT给出回答如下请题主参考
假设我们有一个XML文件如下:
<students>
<student>
<name>Alice</name>
<age>20</age>
</student>
<student>
<name>Bob</name>
<age>25</age>
</student>
</students>
我们想要用Java的XPath来解析这个XML文件并获取每个学生的姓名和年龄。可以使用以下代码:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XmlToObject {
public static void main(String[] args) throws Exception {
// 创建Document对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = factory.newDocumentBuilder().parse("students.xml");
// 创建XPath对象
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
// 获取所有学生节点
NodeList nodeList = (NodeList) xPath.evaluate("//student", document, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Element student = (Element) nodeList.item(i);
// 获取学生姓名和年龄
String name = xPath.evaluate("name", student);
String age = xPath.evaluate("age", student);
System.out.println("Name: " + name + ", Age: " + age);
}
}
}
在上面的代码中,我们首先创建了一个Document
对象来解析XML文件。接着,我们创建了一个XPath
对象,使用evaluate()
方法获取所有学生节点。对于每个学生节点,我们使用evaluate()
方法获取学生姓名和年龄,并将它们打印出来。
如果你运行了上面的代码,却发现获取的值为空,有可能是XPath表达式有误或者XML文件解析错误。可以检查一下XPath表达式是否正确,或者尝试输出document
对象来查看是否成功解析XML文件。