2

I have an xml that has namespace but without prefix. I have xpaths but with prefix that are generated from Schematron. I want to get element detail from that xml using xpath with prefixes.

Here is my XML

<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://foo" type="abc" id="ad">
    <title>Document Title</title>
    <body>
        <p>
            <t>Document Body</t>
        </p>
        <p>
            <t>Document Body</t>
        </p>
        <p>
            <t>Document Body</t>
        </p>
    </body>
</section>

And here is the java code

package com;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XPathTest {
    public static void main(String[] args) {
        File inputFile = new File("files/my_xml.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();

            XPath xPath = XPathFactory.newInstance().newXPath();

            HashMap<String, String> prefMap = new HashMap<String, String>() {
                {
                    put("q", "http://foo");
                }
            };
            SmartContentNameSpaceContext namespaces = new SmartContentNameSpaceContext(prefMap);
            xPath.setNamespaceContext(namespaces);

            String expression = "//q:section[1]";
            NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);

            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);

                System.out.println(node.getAttributes().item(0));
                System.out.println("current element : " + node.getNodeName());
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

I read about NameSpaceContext interface so I have tried

HashMap<String, String> prefMap = new HashMap<String, String>() {
                {
                    put("q", "foo");
                }
            };
MyNameSpaceContext namespaces = new MyNameSpaceContext(prefMap);
xPath.setNamespaceContext(namespaces);

and here is the MyNameSpaceContext

package com;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;

public class MyNameSpaceContext implements NamespaceContext {

    private final Map<String, String> PREF_MAP = new HashMap<String, String>();

    public SmartContentNameSpaceContext(final Map<String, String> prefMap) {
        PREF_MAP.putAll(prefMap);
    }

    @Override
    public String getNamespaceURI(String prefix) {
        return PREF_MAP.get(prefix);
    }

    @Override
    public String getPrefix(String namespaceURI) {
        return null;
    }

    @Override
    public Iterator getPrefixes(String namespaceURI) {
        return null;
    }

}

But this isnot working?

1 Answer 1

1

You need to make sure you use

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);

if you want to use XPath on a DOM tree. I have not looked further for other problems.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.