Question

updated:

I would like to get the value of the arritbute in xsi:noNamespaceSchemaLocation, that is to say: "http://www.mypage/pagedescription.xsd"

<link 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:noNamespaceSchemaLocation="http://www.mypage/pagedescription.xsd">


 ...
 ...

link is an element in my XML File (nearly at the top)

However, the XPATH //n:link/@xsi:noNamespaceSchemaLocation does not work

I tried to modify the context but it still does not work

@Override
public Object executeXpathQuery(Document domDoc, String strQuery) throws Exception {


    System.out.println("executeXpathQuery : strQuery:" + strQuery);

    // output: executeXpathQuery:  strQuery://n:link/@xsi:noNamespaceSchemaLocation
    // so far, it looks OK

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

    final String nonameNamespace = domDoc.getFirstChild().getNamespaceURI();

    NamespaceContext ctx = new NamespaceContext() {
        public String getNamespaceURI(String prefix) {

            String uri = null;
            if ("n".equals(prefix)) {
                System.out.println("using prefix");
                uri = nonameNamespace;
            } 
            else if ("xsi".equals(prefix)) {
                 uri = "http://www.w3.org/2001/XMLSchema-instance";
            }
            return null;
        }
        public String getPrefix(String uri) {
            throw new UnsupportedOperationException();
        }
        public Iterator getPrefixes(String uri) {
            throw new UnsupportedOperationException();
         }
    };


    xPath.setNamespaceContext(ctx);

    XPathExpression xPathExp = xPath.compile(strQuery);


    return (Node) xPathExp.evaluate(domDoc,XPathConstants.NODE);

}

And I made the docuùent builder aware of the context:

    static DocumentBuilder getDocumentBuilder() {
    DocumentBuilderFactory dbf;
    DocumentBuilder db;

    db = null;

    try {
        dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        db = dbf.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
        LogMes.log(XMLFactoryServiceImpl.class, LogMes.ERROR, "Erreur lors de la cràation d'un document DOM. Message: " + e.getMessage());
    }
    return db;
}

I get "using prefix" in the output => this part lokks OK I still get a null value

Any ideas ?

Was it helpful?

Solution

You are 99% of the way there, you just need to make your NamespaceContext return the right thing for the xsi prefix:

    public String getNamespaceURI(String prefix) {

        String uri = null;
        if ("n".equals(prefix)) {
            System.out.println("using prefix");
            uri = nonameNamespace;
        } else if ("xsi".equals(prefix)) {
            uri = "http://www.w3.org/2001/XMLSchema-instance";
        }
        return uri;
    }

Also, if you are creating the domDoc by parsing XML using a DocumentBuilder then you must ensure that the builder is namespace-aware by calling docBuilderFactory.setNamespaceAware(true) before .newDocumentBuilder(). For what I can only presume are historical reasons, the default for DBF is to parse without handling namespaces, and such a DOM tree won't work with XPath.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top