Question

I know this is so easy and I've spent all day banging my head. I have an XML document like this:

<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms">
<Service>
<Name>WMS</Name>
<Title>Metacarta WMS VMaplv0</Title>
</Service>
<Capability>
<Layer>
<Name>Vmap0</Name>
<Title>Metacarta WMS VMaplv0</Title>
<Abstract>Vmap0</Abstract>
...

There can be multiple Layer nodes, and any Layer node can have a nested Layer node. I can quickly select all of the layer nodes and iterate through them with the following xpath code:

Map<String, String> uris = new HashMap<String, String>();
uris.put("wms", "http://www.opengis.net/wms");
XPath xpath1 = doc.createXPath("//wms:Layer");
xpath1.setNamespaceURIs(uris);
List nodes1 = xpath1.selectNodes(doc);

for (Iterator<?> layerIt = nodes1.iterator(); layerIt.hasNext();) {
            Node node = (Node) layerIt.next();
}

I get back all Layer nodes. Perfect. But when I try to access each Name or Title child node, I get nothing. I've tried as many various combinations I can think of:

name = node.selectSingleNode("./wms:Name");
name = node.selectSingleNode("wms:Name");
name = node.selectSingleNode("Name");

etc etc, but it always returns null. I'm guessing it has something to do with the namespace, but all I'm after is the name and title text values for each one of the Layer nodes I've obtained. Can anybody offer any help:

Was it helpful?

Solution 2

Thanks everybody for the help. It was Michael Kay's last clue that got it for me... I needed to use a relative path from the current node, include the namespace URI, and select from the context of the current node I'm iterating through:

Map<String, String> uris = new HashMap<String, String>();
uris.put("wms", "http://www.opengis.net/wms");
XPath xpath1 = doc.createXPath("//wms:Layer");
xpath1.setNamespaceURIs(uris);
List nodes1 = xpath1.selectNodes(doc);

for (Iterator<?> layerIt = nodes1.iterator(); layerIt.hasNext();) {
    Node node = (Node) layerIt.next();
    XPath nameXpath = node.createXPath("./wms:Name");
    nameXpath.setNamespaceURIs(uris);
    XPath titleXpath = node.createXPath("./wms:Title");
    titleXpath.setNamespaceURIs(uris);
    Node name = nameXpath.selectSingleNode(node);
    Node title = titleXpath.selectSingleNode(node);
}

OTHER TIPS

I believe that Node.selectSingleNode() evaluates the supplied XPath expression with an empty namespace context. So there is no way of accessing a node in no namespace by name. It's necessary to use an expression such as *[local-name='Name']. If you want/need a namespace context, execute XPath expressions via the XPath object.

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