# XPath?



## flashray (14. November 2007)

Hallo,

bräuchte einen etwas komplizierteren XPath Ausdruck. Habs leider nicht selbst lösen können:


```
<?xml version="1.0" encoding="iso-8859"?>
<rss version="0.91">
<channel>
   <channelTitle>SPIEGEL ONLINE</channelTitle>
   <description>Schneller wissen, was wichtig ist</description>
   <language>de</language>

   <item>
      <title>Kriegsverbrechertribunal Den Haag</title>
      <link>http://www.spiegel.de/politik/ausland/0,1519.html</link>
   </item>
   <item>
      <title>Wir sind krank durch Konsolen: Nintendo gegen Wii</title>
      <link>http://www.spiegel.de/netzwelt/web/0,1520.html</link>
   </item>
   <item significant="true">
      <title>Einzelhandel: Ladendiebe stehlen sechs Millionen Euro</title>
      <link>http://www.spiegel.de/wirtschaft/0,1521.html</link>
   </item>
   <item>
      <title>Piloten-Ansage: "Keine Sorge - wir fallen"</title>
      <link>http://www.spiegel.de/reise/aktuell/0,1522.html</link>
   </item>
   <item>
      <title>Palaestinenserkaempfe: Hamas greift durch</title>
      <link>http://www.spiegel.de/politik/ausland/0,1523.html</link>
   </item>
   <item significant="true">
      <title>Markenrechtsstreit: Budweiser erleidet Niederlage</title>
      <link>http://www.spiegel.de/wirtschaft/0,1524.html</link>
   </item>
   <item>
      <title>Machtuebergabe in Bayern: Beckstein an Stoiber ab</title>
      <link>http://www.spiegel.de/politik/deutschland/0,1525.html</link>
   </item>
</channel>
</rss>
```

Die Aufgabenstellung heißt:
Geben Sie alle title-Knoten aus, die das Wort "wir" enthalten und zusätzlich alle link-Knoten, die aus dem Ressort "politik" stammen.

Mein Ansatz bislang ist dieser, er tut aber nicht was ich möchte:

```
/rss/channel/item/*[(contains(text(),"politik") & node-name()="link") | (contains(text(),"wir") & node-name()="title")]
```

http://www.futurelab.ch/xmlkurs/xpath.de.html
Hab hier vergeblich alles mögliche ausprobiert. Vielleicht hätte hier jemand einen Tip für mich. 

Vg Erdal


----------



## deepthroat (15. November 2007)

Hi.





flashray hat gesagt.:


> Mein Ansatz bislang ist dieser, er tut aber nicht was ich möchte:
> 
> ```
> /rss/channel/item/*[(contains(text(),"politik") & node-name()="link") | (contains(text(),"wir") & node-name()="title")]
> ...


Du verwendest die falschen Operatoren. Der | Operator vereinigt 2 Knotenmengen, den & Operator gibt es gar nicht. Du solltest die boolschen Operatoren *and* und *or* verwenden. Siehe z.B. http://www.w3schools.com/xpath/xpath_operators.asp

Gruß


----------



## flashray (15. November 2007)

Hallo deepthroat,

ja mit dem Operator or komme ich ein Stückchen weiter. Jetzt nimmt er beide. Wie kann ich aber einschränken, das er einen Filter nur das Tag link, und den anderen Filter für das Tag title mit einbeziehen soll?


Vg Erdal


----------



## deepthroat (15. November 2007)

flashray hat gesagt.:


> Hallo deepthroat,
> 
> ja mit dem Operator or komme ich ein Stückchen weiter. Jetzt nimmt er beide. Wie kann ich aber einschränken, das er einen Filter nur das Tag link, und den anderen Filter für das Tag title mit einbeziehen soll?


Das geschieht in dem Fall automatisch, da das *and* eine höhere Priorität hat als das *or*. Ansonsten durch Klammerung der Ausdrücke.

Gruß


----------



## flashray (15. November 2007)

Das Problem hierbei ist, das die Funktion node-name(...) einen Parameter erwartet, weiss aber nicht wass ich reinschreiben könnte. Habs mit * oder //* ähnlich versucht ..., ohne Erfolg .


----------



## deepthroat (15. November 2007)

flashray hat gesagt.:


> Das Problem hierbei ist, das die Funktion node-name(...) einen Parameter erwartet, weiss aber nicht wass ich reinschreiben könnte. Habs mit * oder //* ähnlich versucht ..., ohne Erfolg .


Nimm einfach, die Funktion name().

Gruß


----------



## flashray (15. November 2007)

/rss/channel/item/*[contains(text(),"politik") and name()="link" or contains(text(),"wir") and name()="title"]

Ja nun damit ist die Aufgabenstellung fast gelöst. Ich hatte name() garnicht gesehen, da es in der Liste ganz weit unten gesondert war. 

Das letzte was noch fehlt ist, eine case-insensitive Suche. D.h. es sollten auch Vorkommnisse wie "Wir" akzeptiert werden. Ein schachteln mit lower-case() führt aber zu einem Fehler:
contains(lower-case(text()),"wir")


----------



## deepthroat (15. November 2007)

flashray hat gesagt.:


> /rss/channel/item/*[contains(text(),"politik") and name()="link" or contains(text(),"wir") and name()="title"]
> 
> Ja nun damit ist die Aufgabenstellung fast gelöst. Ich hatte name() garnicht gesehen, da es in der Liste ganz weit unten gesondert war.
> 
> ...


Die lower-case Funktion gibt es erst seit XPath 2.0. In XPath 1.0 könntest du die translate Funktion benutzen:
	
	
	



```
translate(name(), "ABCDE...", "abcde...")
```
Gruß


----------



## flashray (15. November 2007)

Vielen Dank für die Unterstützung!

Kennst du vielleicht einen anderen Online Interpreter der auch XPath 2.0 kann? Hab ein Paar ausprobiert, keiner wollte lower-case() akzeptieren.

Oder vielleicht ein Eclipse Plugin das ohne großen Aufwand XPath Ausdrücke auswerten kann?

Vg Erdal


----------



## flashray (15. November 2007)

Ja damit hat es nun endlich geklappt! 


```
/rss/channel/item/*[contains(text(),"politik") and name()="link" or contains(translate(text(), "WIR", "wir"),"wir") and name()="title"]
```


----------



## deepthroat (15. November 2007)

flashray hat gesagt.:


> Vielen Dank für die Unterstützung!
> 
> Kennst du vielleicht einen anderen Online Interpreter der auch XPath 2.0 kann? Hab ein Paar ausprobiert, keiner wollte lower-case() akzeptieren.
> 
> Oder vielleicht ein Eclipse Plugin das ohne großen Aufwand XPath Ausdrücke auswerten kann?


Du könntest den XPath Explorer (http://sourceforge.net/projects/xpe) verwenden.

Gruß


----------



## sim26 (19. November 2007)

Hallo alle Tutorials users,

ich habe bitte ein frage zum Thema XPath mit Java benutzen: 

ich habe mein String so definiert um den ganz xml "rss" nach "wir" zu suchen.
 ich kriege aber nur einem einzigen  Output, und das war die erste knote wo er "wir" findet.   dann hört mein Programme nach weiteren "wir" zu suchen.

String expression = ("rss/channel/item/*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");

ich denke irgendwas habe ich in meinem String Definition falsch geschrieben.

oder?

Danke


----------



## sim26 (19. November 2007)

mein code ist:  


```
import java.io.IOException; import javax.xml.parsers.*; 
import javax.xml.soap.Node;
import javax.xml.xpath.*;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/** * @author Darimont * * TODO Comment me */

import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 
import org.xml.sax.InputSource; 
public class XPathExample {
	/** * Creates a new instance of xpath */ 
	public static void main(String[] args) {
		String expression = ("rss/channel/item/*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");
		InputSource iSource = null; 
	try {
		iSource = new InputSource("test.xml");
	} catch(Exception e) {
		e.printStackTrace(System.out); }
	XPath xpath = XPathFactory.newInstance().newXPath(); 
	try {	
		String output = xpath.evaluate(expression, iSource);
		System.out.println("output: " + output);  
		} catch(XPathExpressionException e) {
			e.printStackTrace(System.out); 
			} catch(Exception e) {
				System.out.println(e.toString()); } } }
```

die Output ist nur:


```
output: Wir sind krank durch Konsolen: Nintendo gegen Wii
```

danke


----------



## sim26 (20. November 2007)

kann mir bitte keiner helfen     ist das so schwer :suspekt:


----------



## deepthroat (20. November 2007)

Hi.





sim26 hat gesagt.:


> ich habe mein String so definiert um den ganz xml "rss" nach "wir" zu suchen.
> ich kriege aber nur einem einzigen  Output, und das war die erste knote wo er "wir" findet.   dann hört mein Programme nach weiteren "wir" zu suchen.
> 
> String expression = ("rss/channel/item/*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");
> ...


Nein. Aber wenn du den XPath einmal anwendest, und einen String zurückbekommst - wie soll das funktionieren, dass du mehrere Resultate erhälst?

Versuch's mal so: 
	
	
	



```
import org.w3c.dom.NodeList;

NodeList nl = (NodeList) xpath.evaluate(expression, iSource, XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); ++i) {
    System.out.println(nl.item(i).getFirstChild().getNodeValue());
}
```
Gruß


----------



## sim26 (20. November 2007)

1000 danke, für die schnelle Antwort.
ich probiere mal dein Vorschlag

bis dann


----------



## sim26 (20. November 2007)

soweit sieht wunderbar aus ;-).
ich habe noch ein frage um mehr wissen zu haben ;-) 
Also mein String habe ich so definiert :

```
String expression = ("rss/channel/item/*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");
```
aber sagen wir so, wenn ich will rausbekommen wo gibt's überall in meinem ganzen xml datei "wir" , die nicht unbedingt von "item" stammen. Wäre das schon möglich?

ich habe einfach so probiert, aber das war nix 

```
String expression = ("/*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");
```

danke


----------



## sim26 (20. November 2007)

HALLO  ICH WARTE NOCH AUF EIN ANTWORT.

DANKE ;-];-];-]


----------



## deepthroat (20. November 2007)

Hi.





sim26 hat gesagt.:


> soweit sieht wunderbar aus ;-).
> ich habe noch ein frage um mehr wissen zu haben ;-)


Dann solltest du mal ein XPath Tutorial durcharbeiten (z.B. http://www.w3schools.com/xpath/)


sim26 hat gesagt.:


> aber sagen wir so, wenn ich will rausbekommen wo gibt's überall in meinem ganzen xml datei "wir" , die nicht unbedingt von "item" stammen. Wäre das schon möglich?
> 
> ich habe einfach so probiert, aber das war nix
> 
> ...


Versuch's mal damit:
	
	
	



```
String expression = ("//*[ contains(translate(text(), \"WIR\", \"wir\"),\"wir\") ]");
```
Gruß


----------



## deepthroat (20. November 2007)

sim26 hat gesagt.:


> HALLO  ICH WARTE NOCH AUF EIN ANTWORT.
> 
> DANKE ;-];-];-]


Sag mal, alles klar bei dir? Das hier ist kein Chat oder Instant Messaging! Wenn ich nicht schon geantwortet hätte, würde ich es mir jetzt schwer überlegen.

Du könntest dir auch mal selbst etwas überlegen bzw. erstmal Google o.ä. verwenden um die Antwort selbst zu finden. Wenn du schon auf andere angewiesen bist, weil du es allein nicht auf die Reihe kriegst, dann gewöhne dir entsprechende Umgangsformen an und halte dich an die Netiquette!

Gruß


----------



## sim26 (21. November 2007)

werde ich machen. danke für die hilfe.


----------

