XPath with namespace in Java

前端 未结 2 1078
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 07:30

I would like to get all the content in between the tags but I do not know how to do this because of the urn: namespace.



        
相关标签:
2条回答
  • 2020-11-27 07:57
    1. Short answer: use XPath local-name(). Like this: xPathFactory.newXPath().compile("//*[local-name()='requestURL']/text()"); will return /CAMERA/Streaming/status
    2. Or you can implement a NamespaceContext that maps namespaces names and URIs and set it on the XPath object before querying.
    3. Take a look at this blog article, Update: the article is down, you can see it on webarchive

    Solution 1 sample:

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

    Solution 2 sample:

    // 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);
    

    Edit

    This is a complete example, it correctly retrieve the element:

    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() + ")");
    }
    
    0 讨论(0)
  • 2020-11-27 07:59

    XML xpath with Namespace

    Simple 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";
    

    Name space 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()";
    

    Supply namespace xml file as a string, to asscerionXpath(namespaceXML, jsonString, expression) method and get result in the form of text/node.

    text() : nine hundred and ninety nine dollars

    node : <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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题