# xml nach Value durchsuchen



## nibblas (16. Jun 2008)

moin

ich habe ein xml das in einer anderen software einen jtree darstellt.

das xml ist folgender massen aufgebaut

ein einzelner node:
<subordinates>
</subordinates>

node mit unternodes:
<subordinates>
    <subordinates>
    </subordinates>
</subordinates>

ich möchte nun das dokument mit xpath nach einem bestimmten wert in irgend einem subordinates durchsuchen.
da ich aber nicht weis wieviele subordinates verschachtelt sind, ergibt sich hier ein problem für mich.

gibt es eine einfache methode dies zu lösen?

gruss


----------



## Marco13 (16. Jun 2008)

Entweder http://java.sun.com/j2se/1.4.2/docs/api/org/w3c/dom/Document.html#getElementsByTagName(java.lang.String) oder (was vielleicht basser ist) rekursiv...

```
find(Node node)
{
    if (node.istDerGesuchte()) freuDich();
    else for (alle Nachfolger von node) find(nachfolger);
    nichtGefunden();
}
```


----------



## nibblas (16. Jun 2008)

getElementsByTagName wird net gehen da alle tags gleich heissen und bloss die value anders ist....
hier mal ein beispiel:

```
<subordinates>
            <uid>b8493bc8-0cb3-42ec-bbb6-4aa252a3a61b</uid>
            <cn>Galala</cn>
            <time>2008-04-26T14:20:07.252+02:00</time>
            <iconSetId>79287177-05a3-4206-a0a4-7ad67b72cb7f</iconSetId>
            <nodeType>WhitePageUser</nodeType>
            <organisationId>e931d89a-31fa-4d77-a7cc-6711cf158f4c</organisationId>
            <referenceId>17f12a79-4a60-43ef-806b-3f22ea1a68c8</referenceId>
            <nodeStatus>Undefined</nodeStatus>
            <versionId>78234cf8-c72c-4a78-a5d2-f03cd640791f</versionId>
            <entityType/>
            <staff>false</staff>
            <visibleInOrgChart>false</visibleInOrgChart>
            <description/>
        </subordinates>
        <subordinates>
            <uid>1bcbff4e-2243-40c1-92fa-4b8c8af620b2</uid>
            <cn>Blubb</cn>
            <time>2008-04-26T14:20:07.755+02:00</time>
            <unitInChargeId>3c756c45-ad2e-4ad6-bf3e-ae0ca89691d5</unitInChargeId>
            <iconSetId>df5f5410-ba52-49ed-815a-cf504d0c4bc3</iconSetId>
            <nodeType>WhitePageUser</nodeType>
            <organisationId>e931d89a-31fa-4d77-a7cc-6711cf158f4c</organisationId>
            <referenceId>1df5c94b-b713-4002-9f74-cb0bc59e6167</referenceId>
            <nodeStatus>Undefined</nodeStatus>
            <versionId>431de0d3-71c2-4758-a897-a44303a9c1ff</versionId>
            <entityType/>
            <staff>false</staff>
            <visibleInOrgChart>false</visibleInOrgChart>
            <description/>
            <staticDeviceIdList>352022000361343</staticDeviceIdList>
        </subordinates>
```

ich möchte nun z.B nach dem node cn mit der value Blubb suchen...


----------



## nibblas (18. Jun 2008)

niemand ne ahnung???


----------



## Niki (18. Jun 2008)

Hier ein Beispiel mit Verwendung von jdom:

```
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

public class XPathFinder {

	private Document doc = null;

	public XPathFinder(byte[] xmlData) throws IOException, JDOMException {
		SAXBuilder builder = new SAXBuilder();
		ByteArrayInputStream bis = null;
		try {
			bis = new ByteArrayInputStream(xmlData);
			doc = builder.build(bis);
		} finally {
			if (bis != null)
				bis.close();
		}
	}	
	
	public List find(String xpath) throws JDOMException {
		XPath xp = XPath.newInstance(xpath);
		return xp.selectNodes(doc);
	}
}
```

und hier der Aufruf:

```
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import org.jdom.Element;
import org.jdom.JDOMException;

public class StartXPath {

	/**
	 * @param args
	 * @throws JDOMException
	 */
	public static void main(String[] args) throws IOException, JDOMException {
		File f = new File(args[0]);
		FileInputStream fis = new FileInputStream(f);
		byte[] b = new byte[(int) f.length()];
		fis.read(b);
		fis.close();

		XPathFinder finder = new XPathFinder(b);

		String xpath = "//subordinates[cn='Blubb']";
		List l = finder.find(xpath);
		for (Object o : l) {
			Element e = (Element) o;
			System.out.println(e.getChildText("uid"));			
		}
	}

}
```


----------



## nibblas (18. Jun 2008)

genau den anstoss habe ich gebraucht!!!!

dank dir vielmals


----------



## Marco13 (18. Jun 2008)

Mit getElementsByTagName bekomt man nur das Problem der unbekannten Tiefe in den Griff. Dass man die Liste dann noch durchsuchen muss, ist ja kl... ich dachte, das wäre klar.


----------



## nibblas (19. Jun 2008)

wie meinst du das genau mit der tiefenfindung mit getElementsbyTagName?

<subordinates> über tag
   <subordinates>unter tag
   </subordinates>
</subordinates>

die heissen ja in jeder stufe gleich... wie soll ich da mit getElementsbyTagName arbeiten?


----------



## Marco13 (19. Jun 2008)

Man bekommt eine Liste mit Nodes, und geht diese Liste dann durch, und schaut, ob diese Nodes ein "<cn>Blubb</cn>" enthalten. 

Ich muss aber auch zugeben, dass ich mich mit dem "Xpath"-Zeug (das erst seit Java 1.5 dabei ist) noch nicht beschäftigt habe, das aber beim ersten Überfliegen recht elegant (und vielleicht auch "bequemer" als mein Lösungsvorschlag) aussieht... Werd' ich mir auf jeden Fall mal näher ansehen  :###


----------

