2010-10-14 7 views
9

Ich konnte den folgenden Xpath-Ausdruck nicht ausführen, wenn das Präfix für das XML-Pfadnamespace festgelegt wurde.Xpath-Ausdruck aus XML mit Namespacepräfix

/bk:BookStore/bk:Books/bk:Book[text()='Time Machine']

XML ist:

<BookStore xmlns:bk="http://www.bookstore.com/book#"> 
    <bk:Books> 
    <bk:Book id="1">Time Machine></bk:Book> 
    </bk:Books> 
</bk:BookStore> 
+0

Veröffentlichen Sie den Code, der die XPath-Abfrage ausführt. – Tomalak

+3

Sie müssen die Präfix/Namespace-URI-Bindung an Ihre XPath-Engine übergeben. Warum? Weil Präfixe für den Namenstest nicht wichtig sind, aber der Namespace-URI. So kann 'a: node'' 'b: node' 'auswählen, solange' a' und 'b' Präfixe an denselben Namespace-URI binden. –

Antwort

12

Ohne weitere Informationen über die Host-Sprache (in dem Sie versuchen, XPath-Ausdrücke zu bewerten) es nicht möglich ist eine nützliche Empfehlung zu geben.

Im Allgemeinen muss man einen Namespace mit einem Namespace-Manager "registrieren" und dem registrierten Namespace ein Präfix zuweisen. Wenn Sie dann dieses NamespaceManager-Objekt als Argument für die XPath-Evaluierungsmethode verwenden, können Sie als Argument für diese Methode einen XPath-Ausdruck angeben, der Namen enthält, denen dieses Präfix vorangestellt ist.

Umgehungen:

/*/*[name()='bk:Books']/*[name()='bk:Book' and text()='Time Machine'] 
+0

Ich benutze XML-Signatur in Java. Ich wähle die zu signierenden Elemente mit Hilfe von xpath im Abschnitt "trasnforms". Wie gebe ich den Xpath-Ausdruck, wenn ich Präfixe und Namespaces in meinem XML-Dokument habe. – Ashwin

+1

@Ashwin: Diese Antwort zeigt genau, wie man das macht (eine der möglichen Möglichkeiten), ohne Namespaces zu registrieren. Die zweite Möglichkeit besteht darin, den Namespace für Präfixbindungen zu registrieren, in denen die im XPath-Ausdruck referenzierten Elementnamen stehen - dann kann der XPath-Ausdruck Präfixe enthalten und besser lesbar sein. Dieser zweite Weg erfordert, dass für den Namespace Implementierungs-APIs registriert werden und man die entsprechende Dokumentation lesen muss. –

24

Oder noch besser (und mehr tragbar), ohne unnötigen Präfix:

/*/*[local-name()='Books'] ... and so on 

The function local-name ein beliebiges Präfix ignoriert, die, wie richtig durch commen angegeben, kann variieren.

+1

Warum hat jemand das abgelehnt? Ich fand dies eine ausgezeichnete Lösung, um den Umgang mit Namensräumen zu vermeiden, die in 99% der Fälle nur lästig und unnötig sind. – Arne

+0

Wenn die Namespaces nur eine Hürde sind, müssen Sie vorbeikommen, extern auferlegt - wie es oft der Fall ist - dann ist dies definitiv der richtige Weg. – joachim