CS639 XPath Processing using DOM, with Namespace Prefixes

 

catalog1.xml (catalog.xml: same using default namespace)

<?xml version="1.0"?>

<e:catalog xmlns:e="http://www.edankert.com/examples/">

  <e:cd>

    <e:artist>Stoat</e:artist>

    <e:title>Future come and get me</e:title>

  </e:cd>

  <e:cd>

    <e:artist>Sufjan Stevens</e:artist>

    <e:title>Illinois</e:title>

  </e:cd>

  <e:cd>

    <e:artist>The White Stripes</e:artist>

    <e:title>Get behind me satan</e:title>

  </e:cd>

</e:catalog>

 

 

Showing TestXPathIgnoreNS works OK for default-NS XML:

 

C:\cs\cs639\DOM>java TestXPathIgnoreNS catalog.xml

Enter XPath expression:

//cd

Using file catalog.xml, xpath = //cd

Report of node.toString's and paths of all hits:

[cd: null] /catalog/cd

[cd: null] /catalog/cd

[cd: null] /catalog/cd

String value of first hit:

 

    Stoat

    Future come and get me

 

Showing TestXPathIgnoreNS fails to find elements that have prefixes

In the XML:

 

C:\cs\cs639\DOM>java TestXPathIgnoreNS catalog1.xml

Enter XPath expression:

//cd               ß or //e:cd, same results

Using file catalog1.xml, xpath = //cd

Report of node.toString's and paths of all hits:

String value of first hit:

 

Getting Prefixes to Work: need to set up a NamespaceContext object

and provide it to the XPathFactory--

XPathExample.java in $cs639/xpath

Note useful capability of doing XPath on an already created DOM

 

// Show how to use XPath when the XML has a namespace.

// See the catalog.xml file in this directory (using default NS)

// and the catalog1.xml file that is edited to use a prefix e:

// This program is available from http://www.edankert.com/defaultnamespaces.html

// in the linked xpath-examples.zip

 

// We need to provide the XPath processor with a way to look up prefixes

// we use in the XPath expression.  Here we just set up one prefix "edx"

// to be used for the NS in the XML file, and then use it in the XPath

// expression //edx:cd  to find all the cd elements in the XML file,

// (whatever their prefix is in the XML file.)

 

import javax.xml.namespace.NamespaceContext;

import …

 

public class XPathExample {

 

    public static void main(String[] args) {

        try {

            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();

            domFactory.setNamespaceAware(true);  ßalso set coalescing here

            DocumentBuilder builder = domFactory.newDocumentBuilder();

            Document document = builder.parse(new InputSource(args[0]));

 

            XPathFactory factory = XPathFactory.newInstance();

            XPath xpath = factory.newXPath();

            xpath.setNamespaceContext(new NamespaceContext() { ßanonymous class in use

 

                public String getNamespaceURI(String prefix) { ßoverriding NamespaceContext’s

                    if (prefix.equals("edx")) {

                        return "http://www.edankert.com/examples/";

                    }                          ß can go on with other cases here

                    return "";

                }

 

                public String getPrefix(String namespaceURI) {

                    if (namespaceURI.equals("http://www.edankert.com/examples/")) {

                        return "edx";

                    }

                    return "";

                }

 

                public Iterator<String> getPrefixes(String namespaceURI) {

                    List<String> list = new ArrayList<String>();

                    if (namespaceURI.equals("http://www.edankert.com/examples/")) {

                        list.add("edx");

                    }

                    return list.iterator();

                }

            });

                                       

            Object nodes = xpath.evaluate("//edx:cd", document.getDocumentElement(), XPathConstants.NODESET);

 

            if (nodes instanceof NodeList) {

                for (int i = 0; i < ((NodeList)nodes).getLength(); i++) {

                    System.out.println(((NodeList)nodes).item( i).getTextContent());

                }

            }

 

        } catch (ParserConfigurationException e) {

            e.printStackTrace();

        } catch (XPathExpressionException e) {

            e.printStackTrace();

        } catch (SAXException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

dbs2(13)% java XPathExample catalog.xml   ß or catalog1.xml, same results: finds elements

 

    Stoat

    Future come and get me

 

 

    Sufjan Stevens

    Illinois

 

 

    The White Stripes

    Get behind me satan