# key aus xml lesen mittels jdom



## rtt (14. Feb 2007)

Hallo,
ich bin noch neu auf dem gebiet. Hab mal versucht eine xml mittels jdom ein zu lesen. Soweit so gut, nur stellt sich mir jetzt die Frage, wie ich an ein bestimmtes Element heran komme.

Meine xml sieht folgendermaßen aus:

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    

    
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename"><value>messages</value></property>
    </bean>

    <bean id="externalFileDeleteListener" class="com.rtt.portal2.core.hibernate.ExternalFileDeleteListener">
    </bean>

    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource"><ref bean="dataSource"/></property>
        <property name="mappingResources">
            <list>
                <value>com/rtt/portal2/core/entities/Screenshot.hbm.xml</value>
                <value>com/rtt/portal2/core/entities/Content.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
                <prop key="hibernate.cache.query_cache_factory">org.hibernate.cache.StandardQueryCacheFactory</prop>
                
            </props>
        </property>
        
    </bean>
</bean>
```

Mich interresiert nun das prop-Element mit dem key "hibernate.dialect". Wie kann ich das auslesen, um später den Text des Elements zu ändern?

Habs bisher so probiert. Nur komme ich da irgenwie nicht weiter.

```
public void readApplicationContextXML(String path) {
		
		File xmlFile = new File(path);
		try {
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(xmlFile);
			DocType docType = doc.getDocType();
			
			Element beans = doc.getRootElement();
			Element propDialect = beans.getChild("bean");
			List prop = propDialect.getContent();
			
		} catch(IOException e) {
			System.out.println("Read error");
		} catch(JDOMException j) {
			System.out.println("jdom error" + j);
		}
	}
```

Kann mir da jemand weiter helfen?

Danke 
Gruß Robin


----------



## Corpse (14. Feb 2007)

Schaut bis jetzt eh nicht schlecht aus. Jetzt iterierst noch über die Liste und suchst ein Element, das ein Attribut "key" mit dem gesuchten Wert besitzt. 

Als Alternative kannst noch XPATH verwendent. Damit kannst direkt auf das gesuchte Element zugreifen. Dazu musst dir allerdings noch die Datein jaxen-core.jar, jaxen-jdom.jar und sax-path.jar in den Classpath einbinden.

Das ganze rennt dann so ab:

```
XPath xpath = XPath.newInstance("hier der xpath ausdruck");
Object o = xpath.selectSingleNode(XMLDokument);
```

Hoffe das hilft dir weiter.


----------



## rtt (15. Feb 2007)

Hallo,
vielen Dank für den Tip.
Hab das ganze nun mal mit XPath probiert. 


```
public void readApplicationContextXML(String path) {
		
		File xmlFile = new File(path);
		
		try {		    
			SAXBuilder builder = new SAXBuilder(); 
		    Document document = builder.build(xmlFile);
		    
		    Element rootElement = document.getRootElement(); 
		    String xpathQuery = "//beans/bean/property[@name='hibernateProperties']/props/"; 
		    List<Element> list = XPath.selectNodes(rootElement, xpathQuery); 

			for (Element testElement : list) 
			{
			     // get the prop element 
				Element propElement = testElement.getChild("prop"); 
							
				List<Element> varParamList = XPath.selectNodes(propElement, "//prop[@key='hibernate.dialect']"); 
				for (Element varParamElement : varParamList) 
				{ 
					System.out.println("var-param:" + varParamElement.getText()); 
				}
			}
			
		} catch(IOException e) {
			System.out.println("Read error");
		} catch(Exception e) {
			System.out.println("Exception" + e);
		}
	}
```

Leider bekomme ich immer eine Exception:

```
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/jaxen/BaseXPath
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Unknown Source)
	at org.jdom.xpath.XPath.newInstance(XPath.java:126)
	at org.jdom.xpath.XPath.selectNodes(XPath.java:337)
	at com.rtt.configEditor.PortalConfigEditorApplicationContext.readApplicationContextXML(PortalConfigEditorApplicationContext.java:26)
```

Was habe ich falsch gemacht?

Oder mache ich das schon zu umständlich? Kann man direkt auf das gesuchte Element zugreifen, ohne sich eine Liste mit Elementen geben zu lassen?

Gruß Robin


----------



## rtt (15. Feb 2007)

Die Fehlermeldung war darauf zurück zu führen, dass ich jaxen-core.jar, jaxen-jdom.jar und saxpath.jar in den classpath mit aufnehmen muss.

Hab das ganze auch zum laufen bekommen und kann nun auf den gesuchten Text zugreifen.


```
public void readApplicationContextXML(String path) {
		
		File xmlFile = new File(path);
		
		try {			
		    SAXBuilder builder = new SAXBuilder();
		    Document document = builder.build(xmlFile);
		  	
		    Element rootElement = document.getRootElement();
		        
		    String query = ".//ns:prop[@key='hibernate.dialect']/text()";
		    Object test = XPath.selectSingleNode(rootElement, query);
		    		    
		    System.out.println(test.toString());
			
		} catch(IOException e) {
			System.out.println("Read error");
		} catch(Exception e) {
			System.out.println("Exception: " + e);
		}
	}
```

Nur finde ich, dass es ziemlich lange dauert (2-3 sekunden), bis er das xml gelesen hat.
Gibt es möglichkeiten, das zu beschleunigen?

Gruß Robin


----------



## Corpse (15. Feb 2007)

Na ja, Problem bei JDOM ist, dass das XML-Dokument komplett im Speicher gehalten wird um Veränderungen und einen flexibleren Zugriff zuzulassen. Falls du nur das Dokument einlesen willst, es allerdings nicht verändern willst, würd ich dir die Verwendung von SAX empfehlen. Das ist nicht so speicherintensiv wie die ganzen DOM Derivate, lässt allerdings auch keine Manipulationen am XML-Dokument zu.


----------



## rtt (15. Feb 2007)

dann werd ich wohl bei jdom bleiben. Danke


----------

