# Wie kann ich aus diesem XML eine XMLTABLE-Funktion bauen?



## ebruss17 (10. Feb 2015)

Hallo Leute,

ich habe eine Datenbanktabelle erstellt:

```
CREATE TABLE "MGMT"."SYSTEM" 
(   "SYSTEM_ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 NO CYCLE CACHE 20),
        "NAME" VARCHAR(300) NOT NULL,
        "SERVICE" VARCHAR(200) NOT NULL,
        "VERSION" VARCHAR(150) NOT NULL,
        "CONFIGURATION" XML NOT NULL
    )
```

das in der Spalte "Configuration" hinterlegtes XML sieht so aus:


```
<?xml version="1.0" encoding="UTF-8"?>
<system xmlns:xi="http://www.w3.org/2001/XInclude" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="SystemConfiguration.xsd" 
        xsi:schemaLocation="http://www.w3.org/XML/1998/namespace ../xinclude/xml.xsd [url=http://www.w3.org/2001/XInclude]XInclude[/url]        ../xinclude/xinclude.xsd ">
<components>
    <component>
        <name>FileNet</name>
        <version>5.2.1.0</version>
        <buildNumber>dap521.000.024</buildNumber>
    </component>
    <component>
        <name>CSS</name>
        <version>IQQD0055E The search server is stopped. It must be started for the tool to run.</version>
    </component>
    <component>
        <name>CSS</name>
        <version>2.1.0.0-1.1-4147.</version>
        <fixpack>FP5</fixpack>
    </component>
    <component>
        <name>TDS</name>
        <version>6.3.1.0</version>
    </component>
    <component>
        <name>ICN</name>
        <version>2.0.2</version>
    </component>
    <component>
        <name>CMIS</name>
        <version>IBM Content Management Interoperability Services for FileNet Content Manager (IBM CMIS) Version 2.0.2.3</version>
    </component>
    <component>
        <name>DB2</name>
        <version>DB2 v10.1.0.2</version>
    </component>
    <component>
        <name>WAS</name>
        <version>8.5.5.1</version>
    </component>
</components>
</system>
```

Nun möchte ich mittels der SQL-XML-Funktion das in der Spalte "Configuration" hinterlegtes XML mithilfe der XML-Table-Funktion transformieren:


```
try {

			connection = DriverManager.getConnection(url, user, password);

			selectKunden = connection
					.prepareStatement("SELECT X.NAME, X.VERSION, X.FIXPACK, X.BUILDNUMBER FROM MGMT.SYSTEM, XMLTABLE('$CONFIGURATION/system/components/component' COLUMNS NAME VARCHAR(30) PATH 'name', VERSION VARCHAR(120) PATH 'version', FIXPACK VARCHAR(30) PATH 'fixpack', BUILDNUMBER VARCHAR(20) PATH 'buildNumber') AS X WHERE MGMT.SYSTEM.SYSTEM_ID = ?");
			selectKunden.setInt(1, zahl);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		try {

			resultSet = selectKunden.executeQuery();

		} catch (SQLException e) {
			e.printStackTrace();
		}
	%>

                <%

        while (resultSet.next()){

                %>
                
                    <%=resultSet %>
                    <%

}
                    %>
	
</body>
</html>
```

Bekomme ich nicht die Tabelle als Ausgabe, sondern das hier:

"com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db com.ibm.db2.jcc.t4.i@a4f686db "


----------



## Harry Kane (10. Feb 2015)

Naja, was erwartest du? Für jeden Eintrag im result set gibtst du eine Stringrepräsentation des result set aus. Wenn ResultSet die toString() Methode nicht überschreibt, gibt es halt diesen etwas kryptischen Output.
Das ist in etwa so sinnlos wie das hier:

```
String[] werte = new String[]{"Eins","Zwei","Drei"};
for(String eintrag: werte){
    System.out.println(werte);
}
```


----------



## ebruss17 (10. Feb 2015)

ich habe es jetzt wenigstens mit der Funktion XMLTABLE hinbekommen, die Spalten mit den jeweiligen Werten auf der JSP-Seite anzuzeigen und habe dafür eine SELECT-Anweisung gebastelt, wie im Folgenden Code zu sehen ist! Ich habe aber jetzt innerhalb den Spalten "FIXPACK" und "BUILDNUMBER" ab und zu NULL-Werte stehen, wenn diese keine Werte enthalten. Wie könnte ich diese innerhalb meines Codes denn abfangen, dass, wenn NULL-Werte innerhalb den beiden Spalten enthalten sind, diese leer sein sollen und nicht das Wort "NULL" da drinnstehen haben. Und die Werte für die "buildNumber" wird nicht ausgegeben. Habe ich da vielleicht im Code, wo die for-Schleifen sind, ne Klammer zu früh geschlossen? Ich wäre für die Unterstützung dankbar!!!


```
try {

            connection = DriverManager.getConnection(url, user, password);

            selectKunden = connection
                    .prepareStatement("SELECT X.NAME, X.VERSION, X.FIXPACK, X.BUILDNUMBER FROM MGMT.SYSTEM, XMLTABLE('$CONFIGURATION/system/components/component' COLUMNS NAME VARCHAR(30) PATH 'name', VERSION VARCHAR(120) PATH 'version', FIXPACK VARCHAR(30) PATH 'fixpack', BUILDNUMBER VARCHAR(50) PATH 'buildNumber') AS X WHERE MGMT.SYSTEM.SYSTEM_ID = ?");
            selectKunden.setInt(1, zahl);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {

            resultSet = selectKunden.executeQuery();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    %>
    <table border="1">
        <tr>
            <%
                ResultSetMetaData rsmd = null;

                rsmd = resultSet.getMetaData();

                int numberOfColumns = 0;
                numberOfColumns = rsmd.getColumnCount();

                for (int i = 1; i <= numberOfColumns; i++) {
            %>
            <th><%=rsmd.getColumnLabel(i)%></th>
            <%
                }
            %>
        </tr>

        <%
            while (resultSet.next()) {
        %>
        <tr>
            <%
                for (int i = 1; i <= numberOfColumns; i++) {
                        if (i != numberOfColumns) {
            %>

            <td><%=resultSet.getString(i)%></td>

            <%
                }
                    }
                }
            %>
        </tr>

    </table>
</body>
```


----------



## Harry Kane (10. Feb 2015)

ebruss17 hat gesagt.:


> Wie könnte ich diese innerhalb meines Codes denn abfangen, dass, wenn NULL-Werte innerhalb den beiden Spalten enthalten sind, diese leer sein sollen und nicht das Wort "NULL" da drinnstehen haben.


In dem du den Wert abfragst, ob er null ist, und wenn ja, lässt du ein "" ausgeben.



ebruss17 hat gesagt.:


> Habe ich da vielleicht im Code, wo die for-Schleifen sind, ne Klammer zu früh geschlossen?


Nu geht es aber ans Eingemachte! Also wenn du an der semantischen Richtigkeit deines Codes zweifelst, solltest du vielleicht erstmal probieren, einen Algorithmus zu programmieren, der die Daten aus der DB ziehen kann und sauber in einem Array oder in einer ArrayList mit Datenobjekten abspeichert. Wenn das steht, dann kannst du drüber nachdenken, wie du diesen Algo am besten in eine JSP packst.
Du versuchts viel zu viel in einen Schritt zu packen, weisst offenbar nicht so richtig, was du tust, und wunderst dich dann über das Ergebnis.
Und zu deiner Frage: dein letztes </tr> steht etwas zu weit hinten. Von den drei geschweiften Klammern in Zeile 50-52 schließt die erste (in Zeile 50) den if-Block, der in Zeile 44 beginnt, die zweite in Zeile 51 die for-Schleife die in Zeile 43 beginnt, und die dritte die while-Schleife, in der du über deinen result set iterierst. Das </tr> steht nach der dritten "}", muss aber natürlich davor stehen.


----------

