# XPath und Namespaces



## peez (1. Apr 2010)

Ich habe ein Dokument das folgendermaßen anfängt:

[XML]<?xml version="1.0" encoding="UTF-8"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdfescription rdf:about=""
    xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
    xmlns:exif="http://ns.adobe.com/exif/1.0/"
    xmlns:xmp="http://ns.adobe.com/xap/1.0/"
    xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"
    xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlnshotoshop="http://ns.adobe.com/photoshop/1.0/"
    xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/"
    xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
    xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
   tiff:ImageWidth="4252"[/XML]

Wie würde ich denn jetzt z.B. an die Node <rdf:RDF...> kommen?

Wie ich schon über google gefunden habe, muss ich zuerst einen NamespaceContext definieren, der die verwendeten Namespaces kennt. Dazu habe ich mir diese kleine Klasse geschrieben:


```
private class MyNamespaceContext implements NamespaceContext {
    private Hashtable<String, String> ns = new Hashtable<String, String>();

    public String getNamespaceURI(String prefix) {
      String uri = ns.get(prefix);
      if (uri == null) {
        return XMLConstants.NULL_NS_URI;
      } else {
        return uri;
      }
    }
    
    public void add(String prefix, String namespaceURI) {
      ns.put(prefix, namespaceURI);
    }

    public String getPrefix(String namespaceURI) {
      Enumeration<String> keys = ns.keys();
      while (keys.hasMoreElements()) {
        String prefix = keys.nextElement();
        if (ns.get(prefix).equals(namespaceURI)) {
          return prefix;
        }
      }
      return null;
    }

    public Iterator getPrefixes(String namespaceURI) {
      // TODO Auto-generated method stub
      return null;
    }
  }
```

Die Node versuche ich dann so zu bekommen:

```
XPath xpath = XPathFactory.newInstance().newXPath();

    MyNamespaceContext nsCtx = new MyNamespaceContext();
    nsCtx.add("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
    nsCtx.add("x", "adobe:ns:meta/");
    nsCtx.add("tiff", "http://ns.adobe.com/tiff/1.0/");
    nsCtx.add("exif", "http://ns.adobe.com/exif/1.0/");
    nsCtx.add("xmp", "http://ns.adobe.com/xap/1.0/");
    nsCtx.add("aux", "http://ns.adobe.com/exif/1.0/aux/");
    nsCtx.add("crs", "http://ns.adobe.com/camera-raw-settings/1.0/");
    nsCtx.add("dc", "http://purl.org/dc/elements/1.1/");
    nsCtx.add("photoshop", "http://ns.adobe.com/photoshop/1.0/");
    nsCtx.add("xmpRights", "http://ns.adobe.com/xap/1.0/rights/");
    nsCtx.add("xmpMM", "http://ns.adobe.com/xap/1.0/mm/");
    nsCtx.add("stRef", "http://ns.adobe.com/xap/1.0/sType/ResourceRef#");
    
    xpath.setNamespaceContext(nsCtx);
    
    
    Node node =
        (Node) xpath.evaluate("/x:xmpmeta/rdf:RDF", myXmlDoc, XPathConstants.NODE);
```

Leider ist node immer null...

Was mach ich falsch?


----------



## Noctarius (1. Apr 2010)

Hast du als XPath expression mal [c]//x:xmpmeta/rdf:RDF[/c] probiert?


----------



## bemar (7. Apr 2010)

Wenn du nicht an XPath hängst empfehle ich dir für XML Handling "JaxB".
Das wandelt dein XML in ein POJO um und du kannst z.B. mit xmpmeta.RDF.Description.xxxxxx an deine Werte rankommen.
Ist echt stressfreier ....

Gruß
Ben


----------



## Noctarius (7. Apr 2010)

Dann muss man aber ein XSD haben ;-)


----------

