BLOB mit XML übertragbar?

Ollek

Bekanntes Mitglied
Hallo,

ist es möglich, ein BLOB aus einer Datenbank in eine XML zu schreiben?
Oder gibt es dort einen Weg, wie es funktioniert? Habe schon einiges ausprobiert, nix geholfen. :(

Viele Grüße
 
N

nillehammer

Gast
Ja gibt es. Für die Übertragung binärer Daten in XML gibt es zwei Datentypen base64Binary und hexBinary.

So gehst Du vor:
- Du nimmst Deinen Blob und wandelst ihn in ein byte-Array um
- Du encodierst das byte-Array z.B. mit commons codec (Base64 (Commons Codec 1.5 API))
- Du schreibst das ergebnis nach xml

Gruß nillehammer
 
Zuletzt bearbeitet von einem Moderator:

AlexSpritze

Bekanntes Mitglied
Ich hätte noch folgende Alternative anzubieten, die ohne zusätzliche Bibliotheken auskommt. Du baust dir eine einfache Wrapper-Klasse für das Byte-Array, das der Bean-Konvention folgt. Objekte davon kannst du einfach mittels java.bean.XMLDecoder und XMLEncoder in XML schreiben und davon auch wieder lesen. Folgender Code ist ungetestet, sollte aber das Schema deutlich machen:

Java:
public class BlobToXMLTest{
  public static class BlobXMLWrapper{
    private byte[] blob;
    public BlobXMLWrapper(){ }
    public void setBlob(byte[] blob) { this.blob=blob; }
    public byte[] getBlob() { return blob; }
  }
  
  public static void main(String[] args) throws Exception{
    
    byte[] BYTE_ARRAY = null; // hier dein byte array, das du aus der DB hast
    BlobXMLWrapper blobXMLWrapper = new BlobXMLWrapper();
    blobXMLWrapper.setBlob(BYTE_ARRAY);
    
    XMLEncoder enc = new XMLEncoder(new FileOutputStream(new File("DATEINAME")));
    enc.writeObject(blobXMLWrapper);
    enc.flush();
    
    XMLDecoder dec = new XMLDecoder(new FileInputStream(new File("DATEINAME")));
    BlobXMLWrapper readObject = (BlobXMLWrapper) dec.readObject();
    byte[] arra = readObject.getBlob(); // Byte-Array ist wieder deserialisiert.
  }
}

PS: Die XMLDecoder und XMLEncoder sollten auch nach Gebrauch geschlossen werden.
 
Zuletzt bearbeitet:
N

nillehammer

Gast
Hallo Alex,
Dein Vorschlag ist schön einfach. Danke für den Tipp. Werde es bestimmt mal benutzen. Allerdings ist die Struktur des erzeugten XMLs ja festgelegt. Deswegen ist XMLEncoder für selbst definierte XML-Strukturen nicht geeignet. Oder habe ich was übersehen?
Gruß nillehammer
 

AlexSpritze

Bekanntes Mitglied
Allerdings ist die Struktur des erzeugten XMLs ja festgelegt. Deswegen ist XMLEncoder für selbst definierte XML-Strukturen nicht geeignet. Oder habe ich was übersehen?

Ich denke, die Struktur des XML kann man hier nicht weiter beeinflussen. Diese XML*coder sind soweit ich das sehe, eine Alternative zur binären Serialisierung (Stichwort Interface Serializable), damit man z.B. die Objekte in der XML-Datei bearbeiten kann. Liegt ja alles in Klartext darin. Aber was meinst du mit selbstdefinierten XML-Strukturen?
Gruß
 

AlexSpritze

Bekanntes Mitglied
Ja, so hab ich das auch verstanden. "Mal schnell und einfach in lesbarer Form den Zustand eines Objekts wegschreiben." gefällt mir
Alles, was man mit XML-Schemas definiert.

Achso, dann ist es nichts für die selbstdefinierten Schemata. Auch ist vom Serialisieren des byte-Arrays hiermit abzuraten, weil die XML bestimmt locker die zehnfache Größe als das Array haben wird ...
 

Wildcard

Top Contributor
Du kannst ein Schema erstellen und dir daraus von EMF Java Klassen generieren lassen.
EMF übernimmt dann das schreiben der XML und das kodieren nach Base64.
 

Ollek

Bekanntes Mitglied
[XML]
<maincat>
<id>1</id>
<app_id>1</app_id>
<lfdnr>1</lfdnr>
<description>Tisch</description>
<color>WHITE</color>
<subcats>
<subcats>
<id>1</id>
<maincat_id>1</maincat_id>
<lfdnr>1</lfdnr>
<description>Tragetaschen</description>
<articles>
<article>
<id>1</id>
<subcat_id>1</subcat_id>
<artnr>0000</artnr>
<lfdnr>1</lfdnr>
<description>Tragetasche Maxi</description>
<img></img>
</article>
</articles>
</subcats>
</maincat>
[/XML]

So sieht meine XML aus. In Das Tag <img></img> muss nun das Image rein.
Bin noch sehr neu auf dem Pfad XML/Java.
Wildcard, deswegen meine Frage an dich, was meinst du da genau?

Was einer weitere Schwierigkeit darstellen wird, wie baue ich die BLOB Konventierung in die Struktur ein?? Ich arbeite mit JDOM..
 

RySa

Bekanntes Mitglied
Hast du jetzt Probleme mit der Konvertierung, oder damit, das konvertierte in die Datei rein zu schreiben ?

Außerdem finde ich die Struktur der XML-Datei hmm... sagen wir mal "nicht so schön". Erstens, hast du glaube ich ein Tippfehler - <subcats> kommt zweimal hintereinander ohne dass, das erste geschlossen wird. Dann hast du noch das root-element <maincat> und irgendwo unter subcats ein element <maincat_id> ... warum nicht einfach so was <maincat id=1>, Elemente können auch Attribute haben, aber das nur so nebenbei.
 
Zuletzt bearbeitet:

Ollek

Bekanntes Mitglied
Bin nun soweit, dass ich die BLOB Datei in ein Byte[] umgewandelt habe. Nun muss ich den Schritt machen, die Daten in die Datei zu schreiben, sprich so zu konventieren, dass ich es in die Datei schreiben kann..
 

RySa

Bekanntes Mitglied
Zum encoden, wie schon vorher beschrieben
Java:
Base64.encodeBase64(byte[])

Was das schreiben angeht, du nimmst entweder JDOM oder SAX/StAX und passt das Programm an die Struktur deiner XML-Datei an und schreibst das kodierte byte[] an die gewünschte Stelle rein. Oder du könntest gleichzeitig mir ein Gefallen tun, und mein Tool ausprobieren, das XML-Dateien bearbeiten kann :) ---> XMLTool

Das wäre dann ungefähr so ein Aufwand:
Java:
	public static void main(String args[]) {
		XMLTool tool;
		try {
			tool = new XMLTool();
			tool.setLoggerLevel(Level.ALL);
			tool.setFormatting(true);
			tool.setFile(new File("src/tests/xml-samples/bloob.xml"));
			XPath xpath = new XPath("maincats/maincat/subcats/subcat/articles/article[aID=1]/img/");
                        byte[] deinBloob = null; //Hier natürlich deine Daten
                        String daten = Base64.encodeBase64String(deinBloob)
			tool.addTextToElement(xpath, daten);
			tool.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
Zuletzt bearbeitet:

Ollek

Bekanntes Mitglied
Werde ich gleich mal ausprobieren.
Aber du sagtest, die Struktur meiner XML Datei passt noch nicht wirklich bzw. ist nicht gut.
Soll ich ID als Attribute speichern??

Bzw. hättest du nen Vorschlag für eine bessere Struktur, ich bin recht neu was XML angeht.. Erstes Programm mit XML :oops:

Die XML Datei soll Hauptkategorien deren Unterkategorien und dessen Artikel speichern. Dort woltle ich nicht 3 XML machen sondern die Unterkategorien und Artikel direkt unter die Hauptkategorien packen.
 

RySa

Bekanntes Mitglied
Also erstens ist dein root-Element nicht wirklich ein Root-Element, es sei dem du hast nur ein Abschnitt gepostet. Zweitens, kann ich es nicht wirklich "verbessern" ohne die ganze Struktur zu kennen, und ohne zu wissen wofür genau und wie es eingesetzt werden sollte. Falls das aber die ganze Datei ist, solltest noch ein "echtes" root-element hinzufügen wie z.b <maincats> (ich nehme mal an, es soll mehr <maincat> Elemente in einer Datei geben.)

Was heißt denn, app_id und was soll die lfdnr heißen in der XML ? Ist denn lfdnr (also Laufende Nummer, nehme ich an) nicht überflüssig wenn es die id gibt ? Und was hat eine Tragetasche in der mainKategorie Tisch verloren ? xD Auch das Color, würde ich nicht unbedingt an die Mainkategorie dran hängen, da dann alle subcats und artikeln weiß sein müssten (also müsstest du für jede Farbe des Tisches, eine maincat haben, nicht wirklich effizient)

Vielleicht so als Prototyp, so etwas ?:
[XML]<?xml version="1.0" encoding="UTF-8" ?>
<maincats>
<maincat mID="1">
<app_id>1</app_id>
<lfdnr>1</lfdnr>
<description>Tisch</description>
<color>WHITE</color>
<subcats>
<subcat sID="1">
<lfdnr>1</lfdnr>
<description>Tragetaschen</description>
<articles>
<article aID="1" aNR="0000">
<lfdnr>1</lfdnr>
<description>Tragetasche Maxi</description>
<img></img>
</article>
</articles>
</subcat>
</subcats>
</maincat>
</maincats>[/XML]
 
Zuletzt bearbeitet:

Ollek

Bekanntes Mitglied
Habe es nun mit folgender Klasse gelöst:

Der Vorteil ist, dass ich keine externe JAR einbinden muss :toll:

Java:
public class Base64Coding
{
  private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
  private static int[] toInt = new int[128];
 
  static
  {
    for (int i = 0; i < ALPHABET.length; i++)
    {
      toInt[ALPHABET[i]] = i;
    }
  }
 
  /**
   * Codiert das übergeben Byte[] in einen Base64-String
   *    *
   * @param Byte[] welches codiert werden soll
   * @return Der Base64-Codierte String
   */
  public static String encode(byte[] buf)
  {
	  
    int size = buf.length;
    char[] ar = new char[((size + 2) / 3) * 4];
    int a = 0;
    int i = 0;
    while (i < size)
    {
      byte b0 = buf[i++];
      byte b1 = (i < size) ? buf[i++] : 0;
      byte b2 = (i < size) ? buf[i++] : 0;
 
      int mask = 0x3F;
      ar[a++] = ALPHABET[(b0 >> 2) & mask];
      ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
      ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
      ar[a++] = ALPHABET[b2 & mask];
    }
    switch (size % 3)
    {
      case 1:
        ar[--a] = '=';
      case 2:
        ar[--a] = '=';
    }
    return new String(ar);
  }
 
  /**
   * Decodiert einen Base64-Codierte String in einen "normalen" String
   *
   * @param base64 Der Base64-Codierte String.
   * @return Der Base64-decodierte String.
   */
  public static String decode(String base64)
  {
    int delta = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
    byte[] buffer = new byte[base64.length() * 3 / 4 - delta];
    int mask = 0xFF;
    int index = 0;
    for (int i = 0; i < base64.length(); i += 4)
    {
      int c0 = toInt[base64.charAt(i)];
      int c1 = toInt[base64.charAt(i + 1)];
      buffer[index++] = (byte) (((c0 << 2) | (c1 >> 4)) & mask);
      if (index >= buffer.length)
      {
        return new String(buffer);
      }
      int c2 = toInt[base64.charAt(i + 2)];
      buffer[index++] = (byte) (((c1 << 4) | (c2 >> 2)) & mask);
      if (index >= buffer.length)
      {
        return new String(buffer);
      }
      int c3 = toInt[base64.charAt(i + 3)];
      buffer[index++] = (byte) (((c2 << 6) | c3) & mask);
    }
    return new String(buffer);
  }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
nrg JAXB generell auf XMLs übertragbar XML & JSON 22

Ähnliche Java Themen

Neue Themen


Oben