2012-05-23 12 views
7

ich eine XPath-Abfrage zu dieser Datei tun möchte (Auszug angezeigt):Java XPath: Abfragen mit Standard-Namespace xmlns

<?xml version="1.0" encoding="UTF-8"?> 
<!-- MetaDataAPI generated on: Friday, May 25, 2007 3:26:31 PM CEST --> 
<ModelClass xmlns="http://xml.sap.com/2002/10/metamodel/webdynpro" xmlns:IDX="urn:sap.com:WebDynpro.ModelClass:2.0"> 
    <ModelClass.Parent> 
     <Core.Reference package="com.test.mypackage" name="ModelName" type="Model"/> 

Dies ist ein Ausschnitt aus dem Code Ich verwende:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = domFactory.newDocumentBuilder(); 
Document document = builder.parse(new File(testFile)); 
XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 
xpath.setNamespaceContext(new NamespaceContext() { 
    public String getNamespaceURI(String prefix) { 
... 

String result = xpath.evaluate(xpathQueryString, document); 
System.out.println(result); 

Das Problem, mit dem ich konfrontiert bin, ist, dass wenn der Standard-Namespace in einer XPath-Abfrage referenziert wird, die getNamespaceURI-Methode nicht aufgerufen wird, um es zu lösen. Diese Abfrage zum Beispiel extrahiert nichts:

//xmlns:ModelClass.Parent/xmlns:Core.Reference[@type=\"Model\"]/@package

Jetzt habe ich versucht, durch Ersetzen xmlns mit einem gefälschten Präfix d und dann entsprechend die getNamespaceURI Methode Schreiben des Parsers „austricksen“ (so http://xml.sap.com/2002/10/metamodel/webdynpro zurückzukehren wenn d angetroffen wird). In diesem Fall wird die getNamespaceURI aufgerufen, aber das Ergebnis der XPath-Ausdrucksauswertung ist immer eine leere Zeichenfolge.

Wenn ich Namespaces aus der Datei und aus dem XPath-Abfrageausdruck ausstrippe, kann ich die Zeichenfolge erhalten, die ich wollte (com.test.mypackage).

Gibt es eine Möglichkeit, Dinge mit dem Standard-Namespace richtig zu machen?

Antwort

8

In Ihrem Namespace Zusammenhang bindet einen Präfix Ihrer Wahl (zum Beispiel df) an den Namespace-URI in dem Dokument

xpath.setNamespaceContext(new NamespaceContext() { 
    public String getNamespaceURI(String prefix) { 
     switch (prefix) { 
     case "df": return "http://xml.sap.com/2002/10/metamodel/webdynpro"; 
     ... 
     } 
    }); 

und dann das Präfix in Ihrem Pfad Ausdrücke verwenden, um Elementnamen zu qualifizieren z.B. /df:ModelClass/df:ModelClass.Parent/df:Core.Reference[@type = 'Model']/@package.

+0

Hallo Martin, ich habe es versucht, aber es funktioniert nicht ... –

+4

Stellen Sie sicher, dass Sie auch einen Namespace bewusst DocumentBuilder erstellen http://docs.oracle.com/javase/6/docs/api/javax/ xml/parsers/DocumentBuilderFactory.html # setNamespaceAware% 28boolean% 29 vor dem Arbeiten mit Namespaces. –

+0

Das hat den Trick gemacht. Ich dachte, dass der DocumentBuilder standardmäßig Namespaces kannte. Danke nochmal. –

10

Die XPath 1.0-Spezifikation erfordert, dass "kein Präfix keinen Namespace bedeutet". Daher ist JAXP, das für XPath 1.0 entwickelt wurde, ziemlich richtig, um zu verhindern, dass Sie das "Null-Präfix" an einen Nicht-Null-Namespace binden.

Mit XPath 2.0 können Sie einen Standardnamespace für nicht qualifizierte Namen in Ihrem XPath-Ausdruck deklarieren, aber um davon profitieren zu können, benötigen Sie eine API (z. B. Saxon s9api), die diese Funktion nutzt.

+0

Danke Michael für die zusätzlichen Informationen. –