# XPath soll XML liefern



## ballibum (5. Sep 2018)

Hallo Forum,

mit 

```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(file);
       
        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
```

lege ich die Grundlagen zum Auswerten eines XML Dokumentes. Nun hole ich mir mit 

```
NodeList nl = (NodeList) xpath.evaluate("//Address", doc, XPathConstants.NODESET);
```
Alle Adressen  aus dem Beispiel und kann diese mit


```
for (int i = 0; i < nl.getLength(); i++) {
            System.out.println(i);
            System.out.println(nl.item(i).getNodeName());
            System.out.println(nl.item(i).getChildNodes());
            NodeList children = nl.item(i).getChildNodes();
            System.out.println(nl.item(i).getTextContent());
        }
```

auswerten, das macht aber irgendwie nur Ärger, gerade wenn, anders als im Beispiel, eine tiefere und unstrukturiertere Verschachtelung anfällt.

Daher würde ich gerne keine NodeList zurück bekommen wollen, sondern erneut XML-Code um diesen dann wieder mit den gängigen XPaths auswerten zu können. Daher meine Frage wie kriege ich xpath.evaluate dazu mir XML zurückzugeben?

beste Grüße
Balli


----------



## Flown (5. Sep 2018)

`xpath.evaluate(".//Subelem/text()", /* Startpunkt */ nl.item(i), XPathConstants.STRING)`

XML wird hier nicht zurückgegeben, sondern der DOM-Tree wird durchlaufen.

Mit Bsp. und konkretem Problem könnte man dir konkreter helfen!


----------



## ballibum (5. Sep 2018)

Hi,
ein Beispiel ist oben verlinkt.

Wenn ich mir da über 
	
	
	
	





```
NodeList nl = (NodeList) xpath.evaluate("//Address", doc, XPathConstants.NODESET);
```
die Address-Geschichten:

```
<Address Type="Shipping"> 
    <Name>Ellen Adams</Name> 
    <Street>123 Maple Street</Street> 
    <City>Mill Valley</City> 
    <State>CA</State> 
    <Zip>10999</Zip> 
    <Country>USA</Country> 
  </Address>
```

hole kann ich nicht mehr über XPaths (weil ich kein XML erhalte) auf die Inhalte zurückgreifen. Sondern muss den Weg über:

```
for (int i = 0; i < nl.getLength(); i++) {
           System.out.println(nl.item(i).getNodeName());
           System.out.println(nl.item(i).getTextContent());
}
```
gehen. Bei so einem einfachen Beispiel ist das kein Problem, jedoch habe ich im realen Leben deutlich verschachtelte Elemente (stark vereinfachtes Beispiel):

```
<gmd:CI_ResponsibleParty>
      <gmd:organisationName>
        <gco:CharacterString>Name</gco:CharacterString>
      </gmd:organisationName>
      <gmd:contactInfo>
        <gmd:CI_Contact>
          <gmd:address>
            <gmd:CI_Address>
              <gmd:electronicMailAddress>
                <gco:CharacterString>name@adresse.de</gco:CharacterString>
              </gmd:electronicMailAddress>
            </gmd:CI_Address>
          </gmd:address>
        </gmd:CI_Contact>
      </gmd:contactInfo>
      <gmd:role>
        <gmd:CI_RoleCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="pointOfContact" />
      </gmd:role>
    </gmd:CI_ResponsibleParty>
```

Um hier schneller an die benötigten Werte zu gelangen, wäre es schön, wenn ich hier wieder die XPath-Funktionen anwenden könnte. Um an die e-Mailadresse zu gelangen ist es sonst echt steinig und ebenso an den codeListValue "pointOfContact".

mit bestem Gruß


----------



## Flown (5. Sep 2018)

XPath1: `//address//electronicMailAddress/*/text()`
XPath2: `//CI_RoleCode/@codeListValue`
(Natürlich um die NS erweitern)


----------



## Flown (5. Sep 2018)

Wie ich bereits sagte du erhälst einen DOM Node und kannst weiterarbeiten. Zu Punkt 1:

```
NodeList nl = (NodeList) xpath.evaluate("//Address", doc, XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); i++) {
  Node address = nl.item(i);
  System.out.println(xPath.evaluate("./Name/text()", address, XPathConstants.STRING));
}
```


----------



## ballibum (5. Sep 2018)

Super, vielen Dank - so klappt es natürlich genauso.

Achtung: Lösung entspricht nicht der originären Frage, ist aber vermutlich deutlich praktikabler und für meine Zwecke ein Traum!


----------



## Flown (5. Sep 2018)

ballibum hat gesagt.:


> Achtung: Lösung entspricht nicht der originären Frage, ist aber vermutlich deutlich praktikabler und für meine Zwecke ein Traum!


Ich finde die Ursprungsfrage wird mit #5 perfekt beantwortet.


----------



## ballibum (6. Sep 2018)

Perfekt auf jeden Fall, aber du hattest geschrieben, das ich ein DOM-Objekt bekomme und kein reines XML-doc. Wie dem auch sei, ich finde die Lösung deutlich besser als meinen originären Plan.


----------

