带有Java中的命名空间的XPath

我想获得所有的标签之间的内容,但我不知道如何做到这一点,因为urn:命名空间。

<urn:ResponseStatus version="1.0" xmlns:urn="urn:camera-org"> <urn:requestURL>/CAMERA/Streaming/status</urn:requestURL> <urn:statusCode>4</urn:statusCode> <urn:statusString>Invalid Operation</urn:statusString> <urn:id>0</urn:id> </urn:ResponseStatus> 

有任何想法吗 ?

谢谢 !

  1. 简短的回答:使用XPath local-name() 。 像这样: xPathFactory.newXPath().compile("//*[local-name()='requestURL']/text()"); 将返回/CAMERA/Streaming/status
  2. 或者你可以实现一个NamespaceContext来映射命名空间的名称和URI,并在查询之前将它设置在XPath对象上。
  3. 看看这篇博客文章

解决scheme1样品:

 XPath xpath = XPathFactory.newInstance().newXPath(); String responseStatus = xpath.evaluate("//*[local-name()='ResponseStatus']/text()", document); System.out.println("-> " + responseStatus); 

解决scheme2样本:

 // load the Document Document document = ...; NamespaceContext ctx = new NamespaceContext() { public String getNamespaceURI(String prefix) { return prefix.equals("urn") ? "urn:camera-org" : null; } public Iterator getPrefixes(String val) { return null; } public String getPrefix(String uri) { return null; } }; XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(ctx); String responseStatus = xpath.evaluate("//urn:ResponseStatus/text()", document); System.out.println("-> " + responseStatus); 

编辑

这是一个完整的例子,它正确地检索元素:

 String xml = "<urn:ResponseStatus version=\"1.0\" xmlns:urn=\"urn:camera-org\">\r\n" + // "\r\n" + // "<urn:requestURL>/CAMERA/Streaming/status</urn:requestURL>\r\n" + // "<urn:statusCode>4</urn:statusCode>\r\n" + // "<urn:statusString>Invalid Operation</urn:statusString>\r\n" + // "<urn:id>0</urn:id>\r\n" + // "\r\n" + // "</urn:ResponseStatus>"; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new java.io.ByteArrayInputStream(xml.getBytes())); XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(new NamespaceContext() { public String getNamespaceURI(String prefix) { return prefix.equals("urn") ? "urn:camera-org" : null; } public Iterator<?> getPrefixes(String val) { return null; } public String getPrefix(String uri) { return null; } }); XPathExpression expr = xpath.compile("//urn:ResponseStatus"); Object result = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) result; for (int i = 0; i < nodes.getLength(); i++) { Node currentItem = nodes.item(i); System.out.println("found node -> " + currentItem.getLocalName() + " (namespace: " + currentItem.getNamespaceURI() + ")"); } 

样品的一个很好的解释可以在这里find

带名称空间的 XML xpath

简单的XML

 String namespaceXML = "<?xml version='1.0' ?><information><person id='1'><name>Deep</name><age>34</age><gender>Male</gender></person> <person id='2'><name>Kumar</name><age>24</age><gender>Male</gender></person> <person id='3'><name>Deepali</name><age>19</age><gender>Female</gender></person><!-- more persons... --></information>"; String jsonString = "{}"; String expression = "//information"; 

名称空间XML

 String namespaceXML = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><m:NumberToDollarsResponse xmlns:m=\"http://www.dataaccess.com/webservicesserver/\"><m:NumberToDollarsResult>nine hundred and ninety nine dollars</m:NumberToDollarsResult></m:NumberToDollarsResponse></soap:Body></soap:Envelope>"; String jsonString = "{'soap':'http://schemas.xmlsoap.org/soap/envelope/', 'm':'http://www.dataaccess.com/webservicesserver/'}"; String expression = "//m:NumberToDollarsResponse/m:NumberToDollarsResult/text()"; 

将namespace xml文件作为string提供给asscerionXpath(namespaceXML, jsonString, expression)方法,并以text / node的forms得到结果。

文字(): nine hundred and ninety nine dollars

节点: <m:NumberToDollarsResult xmlns:m="http://www.dataaccess.com/webservicesserver/"> nine hundred and ninety nine dollars </m:NumberToDollarsResult>

 public static String asscerionXpath(String namespaceXML, String jsonString, String expression){ if(namespaceXML.indexOf("><") > -1) namespaceXML = namespaceXML.replace("><", ">\r\n<"); if(jsonString.indexOf("'") > -1) jsonString = jsonString.replace("'", "\""); System.out.println("namespaceXML : \n"+namespaceXML); System.out.println("nsmespaces : \n"+jsonString); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setNamespaceAware(true); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); try { DocumentBuilder builder = factory.newDocumentBuilder(); Document source = builder.parse( string2Source(namespaceXML) ); XPath xpath = XPathFactory.newInstance().newXPath(); addNameSpaces(jsonString, xpath); // An XPath expression is not thread-safe. Make sure it is accessible by only one Thread. XPathExpression expr = xpath.compile(expression); // The NodeList interface provides the abstraction of an ordered collection of nodes, NodeList nodes = (org.w3c.dom.NodeList) expr.evaluate(source, XPathConstants.NODESET);; Node tree_base = nodes.item(0); return document2String(tree_base); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (XPathExpressionException e) { System.out.println("If the expression cannot be evaluated."); } return ""; } static InputSource string2Source( String str ) { InputSource inputSource = new InputSource( new StringReader( str ) ); return inputSource; } static void addNameSpaces(String jsonString, XPath xpath) { JSONParser parser = new JSONParser(); try { JSONObject namespaces = (JSONObject) parser.parse(jsonString); if (namespaces.size() > 0) { final JSONObject declaredPrefix = namespaces; // To access in Inner-class. NamespaceContext nameSpace = new NamespaceContext() { // To get all prefixes bound to a Namespace URI in the current scope, XPath 1.0 specification // --> "no prefix means no namespace" public String getNamespaceURI(String prefix) { Iterator<?> key = declaredPrefix.keySet().iterator(); System.out.println("Keys : "+key.toString()); while (key.hasNext()) { String name = key.next().toString(); if (prefix.equals(name)) { System.out.println(declaredPrefix.get(name)); return declaredPrefix.get(name).toString(); } } return ""; } public Iterator<?> getPrefixes(String val) { return null; } public String getPrefix(String uri) { return null; } };// Inner class. xpath.setNamespaceContext( nameSpace ); } } catch ( org.json.simple.parser.ParseException e) { e.printStackTrace(); } }