Viele Datenübertragungen verwenden noch immer einfache Textdateien mit festen Feldlängen und jeweils einer Zeile pro Datensatz. Eine einfache Adressenliste könnte zum Beispiel so aussehen:
Torsten Horn Meinestr. 26 52072 Aachen Heinz Hinz Hafenstr. 42 21079 Hamburg Karl Kunz Königstr. 1 50676 Köln
Weiter ist es oft üblich, dass es am Anfang der Zeile einen oder mehrere Header-Blöcke gibt und anschließend beliebig viele Datenblöcke mit sich wiederholendem Format, zum Beispiel so (die Einteilungsleiste dient nur zur Erläuterung und gehört nicht zur übertragenen Datei):
|------- Header ------||----------------- Anschrift ----------------||-- 1. Bestellposten --||-- 2. Bestellposten --||-- 3. Bestellposten --|
Bestellung 2009-09-09Torsten Horn Meinestr. 26 52072 Aachen Java-Buch 33,33EURJava-XML-Buch 55,55EURXML-Buch 77,77EUR Bestellung 2007-08-09Heinz Hinz Hafenstr. 42 21079 Hamburg Hotelführer 111,11EUR Bestellung 2010-01-01Karl Kunz Königstr. 1 50676 Köln Kochbuch 12,34EUR
Der Teil von "Bestellung" bis inklusive des Orts hätte auch als ein einziger Header-Block definiert sein können, aber hier sollen "Bestellung" und Datum als erster Block für den Header gelten sowie Name, Straße und Ort als zweiter Block für die Anschrift. Anschließend folgen beliebig viele Bestellposten-Blöcke, jeweils bestehend aus Buchtitel, Preis und Währung. Im Beispiel enthält die erste Zeile drei Bestellposten und die folgenden nur jeweils einen.
Das folgende Java-Beispiel zeigt, wie sich solche Textformate wahlweise in CSV- oder XML-Dateien transformieren lassen (CSV = Comma separated Values, zu XML siehe java-xml.htm).
Das folgende Beispiel ist kein produktionstaugliches Tool, sondern nur ein Prinzipbeispiel. Zum Beispiel fehlt eine weitergehende Fehlerbehandlung.
Legen Sie beispielsweise folgende Projektstruktur an (oder ein entsprechendes Eclipse-Projekt):
[\MeinWorkspace\XmlUndCsvAusTxt] |- [bin] |- [input] |- [output] '- [src] '- [transformation]
Speichern Sie im src/transformation-Verzeichnis:
TransformationTxtZuCsvUndXml.java
package transformation; import java.io.*; import java.util.*; public class TransformationTxtZuCsvUndXml { public static void main( String[] args ) throws IOException { System.out.println( "\n1. Parameter: CSV-Datei (mit Startspalte;Endspalte;;;Spaltenname)" + "\n2. Parameter: Pfad (mit max. einem '*'-Joker) zu Daten-TXT-Dateien" + "\n3. Parameter: Verzeichnis fuer Ergebnis-CSV-Dateien" + "\n4. Parameter: 1CSV = 1 CSV-Datei, BloeckeCSV = pro Blockgruppe CSV-Datei, XML = XML" + "\n5. Parameter: Encoding (z.B. UTF-8 oder ISO-8859-1)" + "\n6. Parameter: true = mit Leerzeichen-Trim\n" ); if( args.length < 4 ) return; String encoding = ( args.length > 4 ) ? args[4] : "ISO-8859-1"; boolean leerzeichenTrim = ( args.length <= 5 || !args[5].toLowerCase().equals( "false" ) ); String ergebnisDateiFormat = args[3].toLowerCase(); if( ergebnisDateiFormat.equals( "1csv" ) ) { transformiereTxtZuEinerCsvDatei( args[0], args[1], args[2], encoding, leerzeichenTrim ); } else if( ergebnisDateiFormat.equals( "bloeckecsv" ) ) { transformiereTxtZuProBlockCsvDateien( args[0], args[1], args[2], encoding, leerzeichenTrim ); } else if( ergebnisDateiFormat.equals( "xml" ) ) { transformiereTxtZuXML( args[0], args[1], args[2], encoding, leerzeichenTrim ); } else { System.out.println( "Fehler: Ergebnis-Dateiformat muss 1CSV, BloeckeCSV oder XML lauten.\n" ); } } // Transformiere TXT-Datei in eine einzige CSV-Datei: public static void transformiereTxtZuEinerCsvDatei( String propsCsvFile, String txtFilePathAndNamesWithJoker, String outDir, String encoding, boolean leerzeichenTrim ) throws IOException { List<List<TrafoPropsAttr>> trafoPropsBloecke = erstelleListeDerTrafoPropsBloecke( propsCsvFile, encoding ); List<File> files = erstelleListeDerFiles( txtFilePathAndNamesWithJoker ); for( File file : files ) { int anzahlAttrProZeileMin = Integer.MAX_VALUE, anzahlAttrProZeileMax = 0; int anzahlBloeckeMin = Integer.MAX_VALUE, anzahlBloeckeMax = 0; int anzahlZeilen = 0; String line; List<List<String>> attrAll = new ArrayList<List<String>>(); System.out.print( "Inputdatei '" + file.getName() + "': " ); BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), encoding ) ); try { while( (line = in.readLine()) != null ) { List<String> attrZeile = new ArrayList<String>(); int anzahlBloecke = transformiereEinzelneZeileInEineEinzigeListe( line, leerzeichenTrim, trafoPropsBloecke, attrZeile ); if( attrZeile.size() == 0 ) { continue; } anzahlZeilen++; if( anzahlAttrProZeileMin > attrZeile.size() ) anzahlAttrProZeileMin = attrZeile.size(); if( anzahlAttrProZeileMax < attrZeile.size() ) anzahlAttrProZeileMax = attrZeile.size(); if( anzahlBloeckeMin > anzahlBloecke ) anzahlBloeckeMin = anzahlBloecke; if( anzahlBloeckeMax < anzahlBloecke ) anzahlBloeckeMax = anzahlBloecke; attrAll.add( attrZeile ); } } finally { in.close(); } String s1 = (anzahlAttrProZeileMin == anzahlAttrProZeileMax) ? "" : "..." + anzahlAttrProZeileMax; String s2 = (anzahlBloeckeMin == anzahlBloeckeMax) ? "" : "..." + anzahlBloeckeMax; System.out.println( anzahlZeilen + " Zeilen, pro Zeile: " + anzahlAttrProZeileMin + s1 + " Attribute und " + anzahlBloeckeMin + s2 + " Bloecke" ); attrAll.add( 0, erstelleNamenListe( trafoPropsBloecke, anzahlBloeckeMax, false ) ); schreibeCsvDatei( attrAll, outDir, file.getName() + ".csv", encoding ); } } // Transformiere TXT-Datei in pro Blockgruppe jeweils eine CSV-Datei: public static void transformiereTxtZuProBlockCsvDateien( String propsCsvFile, String txtFilePathAndNamesWithJoker, String outDir, String encoding, boolean leerzeichenTrim ) throws IOException { List<List<TrafoPropsAttr>> trafoPropsBloecke = erstelleListeDerTrafoPropsBloecke( propsCsvFile, encoding ); List<File> files = erstelleListeDerFiles( txtFilePathAndNamesWithJoker ); for( File file : files ) { System.out.println( "Inputdatei '" + file.getName() + "':" ); BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), encoding ) ); try { int zeilennummer = 0; String line; while( (line = in.readLine()) != null ) { zeilennummer++; List<List<List<String>>> attrVerschiedeneBloecke = transformiereEinzelneZeileInProBlockEineListe( line, leerzeichenTrim, trafoPropsBloecke ); if( attrVerschiedeneBloecke == null || attrVerschiedeneBloecke.size() == 0 ) { continue; } int blocknummer = 0; for( int i = 0; i < attrVerschiedeneBloecke.size() && i < trafoPropsBloecke.size(); i++ ) { List<List<String>> attrMehrereGleicheBloecke = attrVerschiedeneBloecke.get( i ); attrMehrereGleicheBloecke.add( 0, erstelleNamenListe( trafoPropsBloecke.get( i ), false ) ); String outfilename = file.getName() + "-Zeile" + zeilennummer + "-Block" + ++blocknummer + ".csv"; System.out.println( " CSV-Datei '" + outfilename + "': " + ((attrMehrereGleicheBloecke.size() == 2) ? "1 Block" : (attrMehrereGleicheBloecke.size() - 1) + " Bloecke") ); schreibeCsvDatei( attrMehrereGleicheBloecke, outDir, outfilename, encoding ); } } } finally { in.close(); } } } // Transformiere TXT-Datei in XML-Datei: public static void transformiereTxtZuXML( String propsCsvFile, String txtFilePathAndNamesWithJoker, String outDir, String encoding, boolean leerzeichenTrim ) throws IOException { List<List<TrafoPropsAttr>> trafoPropsBloecke = erstelleListeDerTrafoPropsBloecke( propsCsvFile, encoding ); List<File> files = erstelleListeDerFiles( txtFilePathAndNamesWithJoker ); for( File file : files ) { System.out.println( "Inputdatei '" + file.getName() + "':" ); BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), encoding ) ); try { int zeilennummer = 0; String line; while( (line = in.readLine()) != null ) { zeilennummer++; List<List<List<String>>> attrVerschiedeneBloecke = transformiereEinzelneZeileInProBlockEineListe( line, leerzeichenTrim, trafoPropsBloecke ); if( attrVerschiedeneBloecke == null || attrVerschiedeneBloecke.size() == 0 ) { continue; } String outfilename = file.getName() + "-Zeile" + zeilennummer + ".xml"; System.out.println( " XML-Datei '" + outfilename ); outfilename = concatDirFilename( outDir, outfilename ); BufferedWriter out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( outfilename.trim() ), encoding ) ); try { out.write( "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n<TxtZuXML>\n" ); int blocknummer = 0; for( int i = 0; i < attrVerschiedeneBloecke.size() && i < trafoPropsBloecke.size(); i++ ) { List<List<String>> attrMehrereGleicheBloecke = attrVerschiedeneBloecke.get( i ); attrMehrereGleicheBloecke.add( 0, erstelleNamenListe( trafoPropsBloecke.get( i ), true ) ); out.write( erzeugeXmlAttribute( "Block" + ++blocknummer, attrMehrereGleicheBloecke ) ); } out.write( "</TxtZuXML>\n" ); } finally { out.close(); } } } finally { in.close(); } } } // Transformiere einzelne Zeile in eine einzige Liste: static int transformiereEinzelneZeileInEineEinzigeListe( String line, boolean leerzeichenTrim, List<List<TrafoPropsAttr>> trafoPropsBloecke, List<String> attrZeile ) { int anzahlBloecke = 0; int startIdx = 0; for( List<TrafoPropsAttr> trafoPropsBlock : trafoPropsBloecke ) { startIdx = transformiereEinzelnenBlock( line, startIdx, leerzeichenTrim, trafoPropsBlock, attrZeile ); anzahlBloecke++; } while( startIdx < line.length() ) { int startIdxAlt = startIdx; startIdx = transformiereEinzelnenBlock( line, startIdx, leerzeichenTrim, trafoPropsBloecke.get(trafoPropsBloecke.size() - 1), attrZeile ); if( startIdx != Integer.MAX_VALUE || !line.substring( startIdxAlt, line.length() ).equals( "@" ) ) { anzahlBloecke++; } } return anzahlBloecke; } // Transformiere einzelne Zeile in pro Blockgruppe eine Liste: static List<List<List<String>>> transformiereEinzelneZeileInProBlockEineListe( String line, boolean leerzeichenTrim, List<List<TrafoPropsAttr>> trafoPropsBloecke ) { List<List<List<String>>> attrVerschiedeneBloecke = new ArrayList<List<List<String>>>(); int startIdx = 0; for( int i = 0; i < trafoPropsBloecke.size() - 1; i++ ) { List<List<String>> attrMehrereGleicheBloecke = new ArrayList<List<String>>(); List<String> attrEinBlock = new ArrayList<String>(); startIdx = transformiereEinzelnenBlock( line, startIdx, leerzeichenTrim, trafoPropsBloecke.get( i ), attrEinBlock ); attrMehrereGleicheBloecke.add( attrEinBlock ); attrVerschiedeneBloecke.add( attrMehrereGleicheBloecke ); } List<List<String>> attrMehrereGleicheBloecke = new ArrayList<List<String>>(); while( startIdx < line.length() ) { List<String> attrEinBlock = new ArrayList<String>(); startIdx = transformiereEinzelnenBlock( line, startIdx, leerzeichenTrim, trafoPropsBloecke.get( trafoPropsBloecke.size() - 1 ), attrEinBlock ); if( attrEinBlock.size() > 0 ) { attrMehrereGleicheBloecke.add( attrEinBlock ); } } if( attrMehrereGleicheBloecke.size() > 0) { attrVerschiedeneBloecke.add( attrMehrereGleicheBloecke ); } return attrVerschiedeneBloecke; } static int transformiereEinzelnenBlock( String line, int startIdx, boolean leerzeichenTrim, List<TrafoPropsAttr> trafoPropsBlock, List<String> attrZeile ) { int letzterEndIdx = 0; for( TrafoPropsAttr trafoPropsAttr : trafoPropsBlock ) { int n1 = startIdx + trafoPropsAttr.startSpalte; int n2 = startIdx + trafoPropsAttr.endSpalte; if( line.length() < n1 ) { return Integer.MAX_VALUE; } int n = Math.min( n2, line.length() ); String s = line.substring( n1 - 1, n ); if( n < n2 && s.equals( "@" ) ) { return Integer.MAX_VALUE; } if( leerzeichenTrim ) { s = s.trim(); } attrZeile.add( s ); letzterEndIdx = n2; } return letzterEndIdx; } static List<String> erstelleNamenListe( List<List<TrafoPropsAttr>> trafoPropsBloecke, int anzahlBloecke, boolean konvXmlName ) { int blockNummer = 0; List<String> titel = new ArrayList<String>(); for( List<TrafoPropsAttr> trafoPropsBlock : trafoPropsBloecke ) { blockNummer++; titel.addAll( erstelleNamenListe( trafoPropsBlock, konvXmlName ) ); } while( blockNummer++ < anzahlBloecke ) { titel.addAll( erstelleNamenListe( trafoPropsBloecke.get( trafoPropsBloecke.size() - 1 ), konvXmlName ) ); } return titel; } static List<String> erstelleNamenListe( List<TrafoPropsAttr> trafoPropsBlock, boolean konvXmlName ) { List<String> titel = new ArrayList<String>(); if( konvXmlName ) { for( TrafoPropsAttr trafoPropsAttr : trafoPropsBlock ) { titel.add( trafoPropsAttr.nameXml ); } } else { for( TrafoPropsAttr trafoPropsAttr : trafoPropsBlock ) { titel.add( trafoPropsAttr.nameOrig ); } } return titel; } // Erstelle Liste der Trafo-Props-Bloecke: static List<List<TrafoPropsAttr>> erstelleListeDerTrafoPropsBloecke( String propsCsvFile, String encoding ) throws IOException { List<List<TrafoPropsAttr>> trafoPropsBloecke = new ArrayList<List<TrafoPropsAttr>>(); List<TrafoPropsAttr> trafoPropsBlock = null; BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( propsCsvFile ), encoding ) ); try { String line; int letzteEndSpalte = 0; while((line = in.readLine()) != null) { line = line.trim(); if (line.length() == 0 || line.startsWith( "#" )) { continue; } String[] ss = line.split( ";" ); if( ss.length < 3 ) { continue; } int n = Math.min( 5, ss.length ); TrafoPropsAttr tp = new TrafoPropsAttr(); tp.startSpalte = Integer.parseInt( ss[0].trim() ); tp.endSpalte = Integer.parseInt( ss[1].trim() ); tp.nameOrig = ss[n - 1].trim(); tp.nameXml = konvertiereZuGueltigemXmlNamen( tp.nameOrig ); if( trafoPropsBlock == null || letzteEndSpalte > tp.startSpalte ) { if( trafoPropsBlock != null ) { trafoPropsBloecke.add( trafoPropsBlock ); } trafoPropsBlock = new ArrayList<TrafoPropsAttr>(); } letzteEndSpalte = tp.endSpalte; trafoPropsBlock.add( tp ); } if( trafoPropsBlock != null ) { trafoPropsBloecke.add( trafoPropsBlock ); } } finally { in.close(); } return trafoPropsBloecke; } // Erstelle Liste der Files, maximal ein '*'-Joker ist möglich: public static List<File> erstelleListeDerFiles( String filePathAndNamesWithJoker ) { List<File> resultFiles = new ArrayList<File>(); if(filePathAndNamesWithJoker == null || filePathAndNamesWithJoker.trim().length() <= 0) { return resultFiles; } int n1 = filePathAndNamesWithJoker.lastIndexOf('\\'); int n2 = filePathAndNamesWithJoker.lastIndexOf('/'); int nm = Math.max(n1, n2); if(nm < 1 || nm > filePathAndNamesWithJoker.length() - 2) { return resultFiles; } filePathAndNamesWithJoker = filePathAndNamesWithJoker.trim(); String pathWithoutFilename = filePathAndNamesWithJoker.substring(0, nm); String filenameWithoutPath = filePathAndNamesWithJoker.substring(++nm); nm = filenameWithoutPath.indexOf('*'); String filenameStart = (nm >= 0) ? filenameWithoutPath.substring(0, nm) : filenameWithoutPath; String filenameEnd = (nm >= 0) ? filenameWithoutPath.substring(++nm) : filenameWithoutPath; File[] files = (new File(pathWithoutFilename)).listFiles(); if(files == null || files.length <= 0) { return resultFiles; } for (int k = 0; k < files.length; k++) { if(files[k].isDirectory()) { continue; } String filename = files[k].getName(); if(filename == null || !filename.startsWith(filenameStart) || !filename.endsWith(filenameEnd)) { continue; } resultFiles.add( files[k] ); } return resultFiles; } public static void schreibeCsvDatei( List<List<String>> strListen, String dir, String filename, String encoding ) throws IOException { filename = concatDirFilename( dir, filename ); if( strListen == null || strListen.size() == 0 || strListen.get(0) == null || strListen.get(0).size() == 0 || filename == null || filename.trim().length() == 0 ) { return; } BufferedWriter out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( filename.trim() ), encoding ) ); try { for( List<String> ss : strListen ) { StringBuffer sb = new StringBuffer(); for( String s : ss ) { sb.append( s.replace(';', ',') ).append( ";" ); } if( sb.length() > 0 ) { sb.deleteCharAt( sb.length() - 1 ); out.write( sb.toString() ); out.newLine(); } } } finally { out.close(); } } static String concatDirFilename( String dir, String filename ) { if( filename == null || filename.trim().length() == 0 ) { return null; } filename = filename.trim(); if( dir != null ) { dir = dir.trim(); if( dir.length() > 0 ) { if( !dir.endsWith( File.separator ) ) dir += File.separator; filename = dir + filename; } } return filename; } static String erzeugeXmlAttribute( String blockXmlElementName, List<List<String>> strListen ) { if( strListen == null || strListen.size() < 2 ) { return null; } List<String> namen = strListen.get( 0 ); StringBuffer sb = new StringBuffer(); for( int i = 1; i < strListen.size(); i++ ) { List<String> ss = strListen.get( i ); if( ss == null || ss.size() == 0 ) { continue; } sb.append( " <" ).append( blockXmlElementName ).append( (strListen.size() == 2) ? "" : "-" + i ).append( "\n" ); for( int j = 0; j < ss.size() && j < namen.size(); j++ ) { sb.append( " " ).append( namen.get( j ) ).append( "=\"" ).append( ss.get( j ) ).append( "\"\n" ); } sb.append( " />\n" ); } return sb.toString(); } public static String konvertiereZuGueltigemXmlNamen( String s ) { String[] sonderzeichen = { "ä", "ae", "ö", "oe", "ü", "ue", "Ä", "AE", "Ö", "OE", "Ü", "UE", "ß", "ss", "§", "Paragraph", "\u20AC", "Euro" }; s = s.trim(); for( int i = 0; i < sonderzeichen.length; i+=2 ) { s = s.replace( sonderzeichen[i], sonderzeichen[i+1] ); } for( int i = 0; i < s.length(); i++ ) { char c = s.charAt( i ); if( !(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != '-' && c != '.' && c != '_' ) { s = s.substring( 0, i ) + "_" + s.substring( i + 1 ); } } if( !Character.isLetter( s.charAt( 0 ) ) ) { s = "_" + s; } return s; } } class TrafoPropsAttr { int startSpalte; int endSpalte; String nameOrig; String nameXml; }
Speichern Sie im input-Verzeichnis:
BestellungAbcXyz.txt
Bestellung 2009-09-09Torsten Horn Meinestr. 26 52072 Aachen Java-Buch 33,33EURJava-XML-Buch 55,55EURXML-Buch 77,77EUR Bestellung 2007-08-09Heinz Hinz Hafenstr. 42 21079 Hamburg Hotelführer 111,11EUR Bestellung 2010-01-01Karl Kunz Königstr. 1 50676 Köln Kochbuch 12,34EUR
Falls wie im Beispiel Sonderzeichen und Umlaute ('ö', 'ü') verwendet werden, muss darauf geachtet werden, dass diese Datei in dem angegebenen Encoding gespeichert wird (z.B. ISO-8859-1 oder UTF-8).
Speichern Sie im input-Verzeichnis:
Bestellung-Felddefinitionen.csv
# Header 1; 13; Vorgang 14; 23; Datum # Name und Adresse 1; 15; Name 16; 30; Straße 31; 46; Ort # Bestellposten (beliebig viele) 1; 13; Titel 14; 21; Preis 22; 24; Währung
In dieser Datei wird das Format der Textdateien mit den festen Feldlängen definiert. Hier wurden zwei Header-Blöcke und sich anschließend beliebig oft wiederholende Bestellposten-Blöcke definiert. Pro Datenfeld definiert der erste Wert die Startspalte, der zweite die Endspalte und der dritte Teil ist der Feldname. Der Beginn eines neuen Blocks ergibt sich dadurch, dass der Startspaltenwert kleiner als der letzte Endspaltenwert ist. Falls wie im Beispiel Sonderzeichen ('ß') und Umlaute ('ä') verwendet werden, muss darauf geachtet werden, dass diese Datei in dem angegebenen Encoding gespeichert wird (z.B. ISO-8859-1 oder UTF-8).
Ihr Projektverzeichnis sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\XmlUndCsvAusTxt] |- [bin] |- [input] | |- BestellungAbcXyz.txt | '- Bestellung-Felddefinitionen.csv |- [output] '- [src] '- [transformation] '- TransformationTxtZuCsvUndXml.java
Öffnen Sie ein Kommandozeilenfenster ('Windows-Taste' + 'R', 'cmd'), wechseln Sie in Ihr Projektverzeichnis und kompilieren Sie TransformationTxtZuCsvUndXml.java:
cd \MeinWorkspace\XmlUndCsvAusTxt
javac -d bin src/transformation/TransformationTxtZuCsvUndXml.java
Rufen Sie die Transformation auf (mit dem 4. Parameter "1CSV" für eine einzige CSV-Datei) und sehen Sie sich das Ergebnis entweder in einem Texteditor oder bequemer in Excel an:
java -cp .;bin transformation.TransformationTxtZuCsvUndXml input/Bestellung-Felddefinitionen.csv input/Bestellung*.txt output 1CSV
start output\BestellungAbcXyz.txt.csv
|
Rufen Sie die Transformation auf, diesmal mit dem 4. Parameter "BloeckeCSV", damit pro Blockgruppe jeweils eine CSV-Datei erzeugt wird. Sehen Sie sich die CSV-Dateien an. Die sich wiederholenden Bestellposten ab dem dritten Block in der ersten Zeile finden Sie zum Beispiel in BestellungAbcXyz.txt-Zeile1-Block3.csv:
java -cp .;bin transformation.TransformationTxtZuCsvUndXml input/Bestellung-Felddefinitionen.csv input/Bestellung*.txt output BloeckeCSV
start output\BestellungAbcXyz.txt-Zeile1-Block3.csv
|
Rufen Sie die Transformation diesmal mit dem 4. Parameter "XML" auf. Sie erhalten pro Zeile eine XML-Datei:
java -cp .;bin transformation.TransformationTxtZuCsvUndXml input/Bestellung-Felddefinitionen.csv input/Bestellung*.txt output XML
start output\BestellungAbcXyz.txt-Zeile1.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <TxtZuXML> <Block1 Vorgang="Bestellung" Datum="2009-09-09" /> <Block2 Name="Torsten Horn" Strasse="Meinestr. 26" Ort="52072 Aachen" /> <Block3-1 Titel="Java-Buch" Preis="33,33" Waehrung="EUR" /> <Block3-2 Titel="Java-XML-Buch" Preis="55,55" Waehrung="EUR" /> <Block3-3 Titel="XML-Buch" Preis="77,77" Waehrung="EUR" /> </TxtZuXML>
Die erzeugten XML-Dateien sind sehr rudimentär. Sie können aber leicht zum Beispiel per XSLT in ein anderes gefordertes Format transformiert werden.