Binding namespaces for XPath evaluation in Java

2019-08-19 06:55发布

how to declare a namespace in java, I've tried to declare it inside my main method it asked to "implement all abstract methods", when finish implementing java stated to underlined 50% of my codes in red. How to declare it?? Below is what I've done so far and it is wrong !! please note that the xpath in this example is wrong.Please ignore it, i just want to declare the namespace.

package xpath;

import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;

public class Xpath {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)throws Exception {
    DocumentBuilderFactory Factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = Factory.newDocumentBuilder();
    Document doc = builder.parse("C:/Users/HP/Desktop/solution.xml");

    //creating an XPathFactory:
    XPathFactory factory = XPathFactory.newInstance();
    //using this factory to create an XPath object: 
    XPath xpath = factory.newXPath();
xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro";
        ...
       }
    });
    // XPath Query for showing all nodes value
    XPathExpression expr = xpath.compile("/df:problem/http://df:solutions/df:solution[df:cost/text()=\"505.9208295302417\"]");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;

    for (int i = 0; i < nodes.getLength(); i++) {
//System.out.println("test"+nodes.item(i).getTextContent());
        //System.out.println(nodes.item(i).getElementsByTagName("vehicleId").item(0).getTextContent());
        Element el = (Element) nodes.item(i);
            System.out.println("driverid:" + el.getElementsByTagName("driverId").item(i).getTextContent());
            System.out.println("vehicleId:" + el.getElementsByTagName("vehicleId").item(i).getTextContent());
            System.out.println("Citizen:" + el.getElementsByTagName("act").item(i).getTextContent());
        //System.out.println("Element currently in: " + el.getNodeName());

        if (el.getFirstChild().getNodeType() == Node.TEXT_NODE)
            System.out.println("driverid:" + el.getElementsByTagName("vehicleId").item(i).getTextContent());
        Node vehicle = el.getFirstChild().getFirstChild();

        NodeList children = el.getChildNodes();

    }

        @Override
        public String getPrefix(String namespaceURI) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public Iterator getPrefixes(String namespaceURI) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    }

}

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-08-19 07:21

You've put the two methods getPrefix() and getPrefixes() in the wrong place, they need to be in the anonymous class that implements NamespaceContext:

xpath.setNamespaceContext( new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro";
        ...
       }
    }
@Override
        public String getPrefix(String namespaceURI) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public Iterator getPrefixes(String namespaceURI) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        });

The XPath API in Java, and the NamespaceContext class in particular, is a really bad design - not only do you have to provide the two methods getPrefix and getPrefixes which are never used, but the class provides no way to discover all the (prefix, namespace) pairs that have been bound. If you want something better, turn to Saxon's s9api interface, and then you can use XPath 3.1 as a bonus.

查看更多
登录 后发表回答