[Java] Verwerken van Unicode karakters in ANSI bestand

Pagina: 1
Acties:
  • 489 views sinds 30-01-2008
  • Reageer

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ik ben al een tijdje met dit probleem zoet. Ik heb het eerst via Python geprobeerd en ben nu aan het kijken of ik het met Java kan oplossen.

Het uiteindelijke doel is om XML documenten met speciale karakters erin geparsed te krijgen. Probleem is dat de bestanden ANSI geencodeerd zijn.

Ik heb deze code al gevonden:
code:
1
2
3
4
5
6
7
8
9
10
11
  public static byte[] convert(byte[] data, String srcEncoding, String targetEncoding) {
      // First, decode the data using the source encoding.
      // The String constructor does this (Javadoc).
      String str = new String(data, srcEncoding);

      // Next, encode the data using the target encoding.
      // The String.getBytes() method does this.
      byte[] result = str.getBytes(targetEncoding);

      return result;
  }

...maar die werkt niet omdat deze de speciale chars vervangt met blokjes.

Wat ik nu aan het doen ben is om een ByteArray een voor een uit te lezen. Wat me hier opvalt is dat mijn speciale tekens een negatieve waarde hebben. Ik heb mijn bestand gemaakt door in kladblok de volgende unicode tekens toe te voegen:
€ - Alt+0128
- Alt+0129
‚ - Alt+0130

De negatieve byte waardes die ik nu krijg zijn -128, -127 en -126. Als ik deze nu van 256 aftrek krijg ik de precieze Unicode codes. Ik weet nu alleen niet hoe ik met deze codes nu weer tot de originele tekens kom. Verder heb ik ook het idee dat dit nu niet bepaald de beste oplossing is.

Iemand enig idee hoe ik dit kan aanpakken?

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 17:59

alienfruit

the alien you never expected

ANSI = Windows-1252 = ISO 8859-1

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Als ik dat als encodering voor het bronbestand opgeef dan krijg ik dus een output bestand met drie blokjes...en niet de tekens die ik moet hebben...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Onno
  • Registratie: Juni 1999
  • Niet online
Deddiekoel schreef op donderdag 21 juli 2005 @ 17:27:
De negatieve byte waardes die ik nu krijg zijn -128, -127 en -126. Als ik deze nu van 256 aftrek krijg ik de precieze Unicode codes. Ik weet nu alleen niet hoe ik met deze codes nu weer tot de originele tekens kom. Verder heb ik ook het idee dat dit nu niet bepaald de beste oplossing is.
Dat is het zeker niet nee. Je kunt gewoon iets als een InputStreamReader gebruiken om data in een bepaalde tekenset te lezen, daar hoef je verder zelf niets voor te doen. Verder zou XML altijd wel goed moeten gaan, omdat in de xml header staat welke encoding gebruikt wordt, en de XML parsers die informatie verder gebruiken. (en als je een andere encoding gebruikt dan UTF-8 maar dat niet in de header hebt staan is het gewoon geen geldige XML)

Je kunt dus beter laten zien hoe je die XML probeert te parsen, en wat daarbij dan fout gaat met speciale tekens.

[ Voor 7% gewijzigd door Onno op 21-07-2005 18:42 ]


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 28-11 15:14
Je moet wel heel zeker weten dat je byte[] al in de encoding is die jij denkt dat het is. Anders gaat het al fout bij het gedeelte waarbij je de byte[] omzet in een string. Dan zijn namelijk de characters die je er vervolgens uit krijgt bij het omzetten van de String naar een byte[] zeker fout.

Zo kan je nogal eens de fout in gaan als je een bestand inleest met een een standaard inputstream omdat deze meestal de default encoding gebruikt. Dan kan je beter de bytearrayinputstream gebruiken om het bestand in te lezen. Maar ik weet uiteraard niet of je dat ook hiervoor hebt gedaan.

Misschien kan je daar eerst wat over vertellen want de java code die je hebt neergezet is prima geschikt om byte[]'s te converteren van de ene encoding naar de andere.

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ok, dit is het bestand dat ik inlees, opgeslagen in notepad in ANSI condering:
code:
1
2
3
4
<?xml version="1.0" standalone="yes"?>
<root>
    <book>Weird characters! €&#8218;</book>
</root>

De drie rare characters (€‚) zijn alle drie Unicode tekens (0128, 0129 en 0130). Om te controleren of het bestand doet wat het moet doen moet je hem openen in IE. Deze zou een parse error moeten geven.
Om dit in te lezen naar een byte[] gebruik ik de volgende functie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    public byte[] readFile(File sourceFile){
    try{
        //System.out.println("Start of reading");
        FileInputStream source = new FileInputStream(sourceFile);
        int fileSize = (int)source.getChannel().size();
        byte[] byteOut = new byte[fileSize];
        source.read(byteOut,0,fileSize);
        source.close();
        //System.out.println("Reading done ("+fileSize+" bytes)");
        return byteOut;
    }
    catch(Exception x){
        x.printStackTrace();
        return null;
    }
    }

Waar het allemaal op neer komt is dat er hetzelfde gebeurt als wanneer ik het bestand open in kladblok en opsla als Unicode.

[ Voor 19% gewijzigd door Deddiekoel op 21-07-2005 19:28 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Is er wel een manier om een string object met een unicode code (zoals \u0128) te verwerken tot de bijbehorende char waarde? Beetje zoals de Eval functie van PHP werkt. Ik kan me niet voorstellen dat dit niet zou kunnen.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Deddiekoel schreef op donderdag 21 juli 2005 @ 17:27:
Ik heb mijn bestand gemaakt door in kladblok de volgende unicode tekens toe te voegen:
€ - Alt+0128
� - Alt+0129
‚ - Alt+0130
Nee. De euro is zeker geen U+0080. Die andere karakters komen ook niet netjes op m'n scherm, maar dat verbaast me niets. In Unicode zijn de code points U+0000-U+001F en U+007F-U+009F control-characters en die zijn non-printable.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
MSalters schreef op vrijdag 22 juli 2005 @ 09:44:
[...]
Nee. De euro is zeker geen U+0080. Die andere karakters komen ook niet netjes op m'n scherm, maar dat verbaast me niets. In Unicode zijn de code points U+0000-U+001F en U+007F-U+009F control-characters en die zijn non-printable.
Hoe kom je bij de waardes U+0080? Wat ik schrijf is dat ik met toetsen combi Alt+0128 de tekens heb toegevoegd. Ik ga er dan ook vanuit dat het eruoteken \u0128 is...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
U+0080 is hoe je volgens het Unicode consortium het karakter op codepoint 128 decimaal aanduidt. Lees www.unicode.org maar. Wat Alt+0128 doet weet ik niet, maar als je een euro-teken ziet dan is het getal duidelijk geen Unicode code point. Ik gok dat je te maken hebt met een Windows 8 bits charset, CP1252. In tegenstelling tot wat alienfruit zegt is CP1252 geen ISO-8859-1. Die laatste heeft namelijk geen euro (te oud). De ISO-8859 variant met Euro is -15, en die heeft de euro op 164 zitten.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ah ok, ik bedoelde ook geen codepoints (wwet ook niet wat dat eigenlijk zijn) maar de die eigenlijke code die je met je de unicode escape (\u####) gebruikt. Als je \u0128 uitvoert naar een Unicode aware GUI zie je (als het goed is) €. Ik heb die code nu als string maar ik weet dus niet hoe ik die geparsed oid krijg.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 17:59

alienfruit

the alien you never expected

CP1252 is een uitbreiding (superset of) op de ISO 8859-1karakter set bij mijn weten.

[ Voor 22% gewijzigd door alienfruit op 22-07-2005 12:41 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Deddiekoel schreef op vrijdag 22 juli 2005 @ 12:37:
Ah ok, ik bedoelde ook geen codepoints (wwet ook niet wat dat eigenlijk zijn) maar de die eigenlijke code die je met je de unicode escape (\u####) gebruikt. Als je \u0128 uitvoert naar een Unicode aware GUI zie je (als het goed is) €. Ik heb die code nu als string maar ik weet dus niet hoe ik die geparsed oid krijg.
Lijkt me onwaarschijnlijk, de euro is niet U+0080 maar U+20AC of iets in die richting. De reden is simpel: Unicode code points veranderen nooit. De Euro bestond nog niet toen U+0080 werd vergeven, en sowieso is de range U+00000-U+00FF gelijk aan ISO8859-1

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
alienfruit schreef op vrijdag 22 juli 2005 @ 12:38:
CP1252 is een uitbreiding (superset of) op de ISO 8859-1karakter set bij mijn weten.
Nee. ISO8859-1 heeft alle 256 karakters in gebruik, dus daar valt niet veel meer aan uit te breiden. ASCII is 7 bits, dus daar kun je wel op uitbreiden. Unicode is 20 bits en een superset van ISO8859-1.(ja, ik weet dat 20 een gek getal is - encodings als UTF8 en UTF16 bestaan precies om die reden)

Nogmaals, www.unicode.org heeft al die informatie online, inclusief gratis codepoint charts. De eerste twee (U+0000-U+007F en U+0080-U+00FF) staat ook gewoon op dat het samenvalt met respectievelijk ASCII en de ISO8859-1 uitbreiding op ASCII .

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Maar is er een manier om codepoints aan de byte ontlenen of dus aan de hand van een string met de \U#### code de eigenlijke waarde te krijgen?

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Icelus
  • Registratie: Januari 2004
  • Niet online
MSalters schreef op vrijdag 22 juli 2005 @ 12:58:
[...]

Nee. ISO8859-1 heeft alle 256 karakters in gebruik, dus daar valt niet veel meer aan uit te breiden.
ISO 8859-1 definieert niet het gebied tussen 0x80 en 0x9f.
Bij CP1252 is dit wel het geval. (Zie ook 'overeenkomstige' Unicode code points in afbeelding).

[ Voor 9% gewijzigd door Icelus op 22-07-2005 13:32 ]

Developer Accused Of Unreadable Code Refuses To Comment


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
ISO 8859-1 definieert 'm wel degelijk, je kaart is simpelweg onvolledig. Waar is bijvoorbeeld de Carriage Return en Line Feed? Of de Start Transmission/End Transmission (STX/ETX)? Dat zijn notabene ASCII karakters, en dus zeker ook ISO8859-1

Tweede linkje is wel nuttig, het laat zien dat CP1252 niet simpel te vertalen is naar Unicode.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

paulh schreef op donderdag 21 juli 2005 @ 18:48:
Zo kan je nogal eens de fout in gaan als je een bestand inleest met een een standaard inputstream omdat deze meestal de default encoding gebruikt. Dan kan je beter de bytearrayinputstream gebruiken om het bestand in te lezen. Maar ik weet uiteraard niet of je dat ook hiervoor hebt gedaan.
Nee dat kan dus niet. Een InputStream lees ruwe bytes. Een Reader gebruikt de encoding, omdat die char's returnt in z'n read() en dus een conversie moet doen.

zie ook:
http://java.sun.com/j2se/...a/io/FileInputStream.html
http://java.sun.com/j2se/...i/java/io/FileReader.html

Trouwens:
Als ik dat als encodering voor het bronbestand opgeef dan krijg ik dus een output bestand met drie blokjes...en niet de tekens die ik moet hebben...
Dan hoeft je input encoding dus niet fout te zijn, kan ook je output encoding nog zijn.
Probeer de encoding op te nemen in je xml file (of als dat niet kan, haal hem door een reader met de juiste encoding en parse die input). Kijk dan met een debugger wat er in de string beland.

[ Voor 26% gewijzigd door grhmpf op 22-07-2005 15:31 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Deddiekoel schreef op vrijdag 22 juli 2005 @ 13:21:
Maar is er een manier om codepoints aan de byte ontlenen of dus aan de hand van een string met de \U#### code de eigenlijke waarde te krijgen?
Uit m'n hoofd is hel simpel: Als je letterlijk die \U#### string hebt, dan moet je doen wat een compiler ook doet: vervang die 6 karakters door het enkele Unicode karakter met de waarde ####. Ik weet even niet uit m'n hoofd of die #### een hex nummer of een decimaal nummer is, maar dat zijn details.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ten eerste is het geen geldige XML om een bestand in een karakter-encodering op te slaan anders dan UTF-8 als je dit niet expliciet in de XML declaration aangeeft. Notepad is geen geschikte XML editor wat dat betreft.

Ten tweede laat je in je code nu niet zien hoe je de ingelezen byte array converteert naar een String. Het is juist dit stuk code dat mis gaat. Je zult dezelfde encodering moeten aangeven die gebruikt is door Notepad voor het opslaan om de bytearray weer terug om te zetten naar een String. Het is nutteloos om zelf allerlei codes op te zoeken, de conversie tabellen zitten gewoon in Java en daar kun je gewoon gebruik van maken.

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ok, Notepad gebruikt meen ik ANSI als standaard. Wat is daar de encodering van? ISO 8859-1 heb ik al geprobeerd.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 17:59

alienfruit

the alien you never expected

Latin1 of die Windows karakter set lijkt mij.

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
MSalters schreef op vrijdag 22 juli 2005 @ 17:40:
[...]

Uit m'n hoofd is hel simpel: Als je letterlijk die \U#### string hebt, dan moet je doen wat een compiler ook doet: vervang die 6 karakters door het enkele Unicode karakter met de waarde ####. Ik weet even niet uit m'n hoofd of die #### een hex nummer of een decimaal nummer is, maar dat zijn details.
Ik heb niet letterlijk de code \u#### maar ik heb letterlijk (bijvoorbeeld) \u0128 en ik wil dat deze verwerkt wordt tot €...

Wat is de windows karakterset? CP-1252 werkte niet...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Deddiekoel schreef op vrijdag 22 juli 2005 @ 20:15:
Ok, Notepad gebruikt meen ik ANSI als standaard. Wat is daar de encodering van? ISO 8859-1 heb ik al geprobeerd.
Notepad gebruikt UTF 8 als je Save As UTF-8 encoding gebruikt, of UTF16 als je daarvoor kiest. Duh.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Deddiekoel schreef op zaterdag 23 juli 2005 @ 11:03:
[...]

Ik heb niet letterlijk de code \u#### maar ik heb letterlijk (bijvoorbeeld) \u0128 en ik wil dat deze verwerkt wordt tot €...
Nu zeg je de hele tijd \u0128, maar wat bedoel je daar nou helemaal mee? Als het niet de 6 karakter string is?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
MSalters schreef op zaterdag 23 juli 2005 @ 23:18:
[...]

Nu zeg je de hele tijd \u0128, maar wat bedoel je daar nou helemaal mee? Als het niet de 6 karakter string is?
Ik bedoel daarmee dat ik een String object heb met als inhoud \\u0128 (en dus eigenlijk \u0128) . Nu is het zo dat als je de String "Dat kost veel \u0128" zou hebben dat er zou komen te staan 'Dat kost veel €'

Wat ik wil weten of ik die inhoud van mijn Stringobject kan gebruiken om dus een unicode teken te krijgen?

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
MSalters schreef op zaterdag 23 juli 2005 @ 23:17:
[...]

Notepad gebruikt UTF 8 als je Save As UTF-8 encoding gebruikt, of UTF16 als je daarvoor kiest. Duh.
Als je een nieuw bestand maakt en gewoon saved dan heb je ANSI. Met opslaan als... kun je inderdaad kiezen.

Mijn probleem is (nogmaals) dat het bestand ANSI geencodeerd is maar dat er Unicode tekens in staan. Door deze tekens gaat de XML parser op zijn bek. Waar ik nu naar op zoek ben is een manier om die speciale tekens te behouden zonder dat mijn parser plat gaat....

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Je bedoelt dus dat in jouw bestand tekens staan die voorkomen in de unicode set.

Een byte 128 in CP1252 is niet hetzelfde als \u0128.

Die tekens komen ook voor in CP1252 anders zou je ze niet zien. Dus zeggen dat er "unicode karakters" in voorkomen is wel waar, maar zegt niets :). Unicode is immers de verzameling van alle mogelijke letters, waarbij CP1252 of ANSI daar een deelverzameling van is. Dus nogal logisch dat er unicode karakters in je tekst bestand zitten :P

Wat je in Java moet doen is aangeven wat de source encoding is (ANSI, danwel CP1252) en dan zal Java dat intern omzetten naar unicode. Van belang voor de conversie van bytes naar String.

Alleen in CP1252 is byte 128 gelijk aan de euro. Unicode euro is "\u20ac". (zie http://mindprod.com/jgloss/euro.html).

Een klein testje toont aan dat Java het prima doet mits de encoding goed staat:
Java:
1
2
        String s = new String(new byte[]{(byte)128}, "CP1252");
        System.out.println(s);

(Op windows werkt dat ook zonder de encoding omdat de platform encoding al CP1252 is)

Dus mijn vermoeden is dat je op een vreemde manier je xml inleest waardoor de encoding vertaling niet wordt gemaakt. Anders zou je byte 128 wel naar unicode \u20ac geconverteerd worden. Is je bestand stiekem toch in UTF-8?

Nog een ding wat je kan checken (weet niet of dat uitmaakt, gokje): de JRE is in een Engelse en in een Internationale smaak te krijgen. Zorg dat je die laatste versie draait.

Geef eens wat code van je xml inlezer, want ik gok dat daar de fout zit.

[ Voor 21% gewijzigd door grhmpf op 24-07-2005 12:29 ]


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ik heb het volgende gedaan. Ik heb in kladblok een XML bestand gemaakt en opgeslagen. Daarna open ik datzelfde bestand en voeg met toetscombinatie Alt+0128, Alt+0129 en Alt+0130 wat speciale tekens toe en sla dit weer gewoon op (dus niet via opslaan als). Als ik het XML bestand nu wil openen in IE dan krijg ik een parsing error. Ook als ik aan de XML een encoding="URT-8" (oid) toevoeg. Mijn doel is om mijn XML bestand (dat dus de fout is IE geeft) zo op te slaan dat hij wel in IE geopent kan worden.

Ik kan dit handmatig erg eenvoudig doen door het bestand in kladblok te openen en dan via Opslaan Als... op te slaan als Unicode. Maar dit proces wil ik dus automatiseren. Tot nu toe ben ik het dichts bij gekomen door de tekst in te lezen als Byte array en zo te proberen de tekens leesbaar te krijgen. Uitgaande van de byte waardes (-128 voor mijn Alt+0128 invoer) wilde ik de originele code herstellen. Ik zag ook wel in dat dit waarschijnlijk niet de juiste manier was om te gaan maar ik kan gewoon niets anders bedenken...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Ja dat had ik wel begrepen. De vraag was hoe je in code die file leest. Ik ga even snel kijken of ik het kan reproduceren :)

Oh dat is snel...mijn eerste xml file, gewoon in ISO8859-1 opgeslagen (CP1252,ANSI,DOS wat je wilt)).

XML:
1
2
3
<root>
<bla>value met rare tekens &#8218; dat waren ze</bla>
</root>


Dan gaan de rare tekens verloren als ik de xml check in firefox. Ik neem aan dat firefox default naar UTF-8 bij geen encoding (en dat is het dus niet).

Voeg ik de encoding toe:
XML:
1
2
3
4
<?xml version="1.0" encoding="ISO8859-1"?>
<root>
<bla>value met rare tekens &#8218; dat waren ze</bla>
</root>

Dan werkt het al in firefox. Ik geef dus aan dat het bestand ANSI is! Je moet dus geen UTF-8 daar neerzetten want dat gaat niet werken, je karakterset is immers ANSI. Als jij het bestand opslaat in UTF-8 vanuit notepad, dan doet notepad die conversie al voor je, vandaar dat het werkt.

Dus gewoon die encoding regel erbij plempen en dan gaat het zeker werken, als je de xml tenminste wil parsen.

Als je alleen die conversie van het bestand wil automatiseren dan pak je in java een FileReader waarbij je de encoding CP1252 geeft en alles wat je uit die reader leest schrijf je gelijk via een FileWriter met UTF-8 charset weer weg, of je plempt de encoding regel erboven natuurlijk.

[ Voor 90% gewijzigd door grhmpf op 24-07-2005 15:43 ]


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ok, ik zal het eens gaan doen. Ik heb wel dat direct lezen en schrijven geprobeerd maar niet met het opgeven van encondings. Heb jij bovenstaande ook al in IE geprobeerd? Ik ga het iig even proberen! Thanks

Edit: Ik heb het even geprobeerd en het werkt! Ik was er echt heilig van overtuigd dat dit niet zou werken en had hier ook al 'bewijzen'van gevonden op internet. Wat ik zelf had getest was om de via de XML tag de encoding op "UTF-8" te zetten en dat werkte dus niet...
Ik ben nog niet in de gelegenheid om dit alles in Java (en Python) te testen. Wat ik me nu ook afvraag is of er een manier is om de encodering van een bestand te detecteren.

[ Voor 53% gewijzigd door Deddiekoel op 24-07-2005 16:39 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Volgens mij had je "encoding" van xml verkeerd begrepen, want encoding geeft aan welke encoding het bestand heeft, niet welke encoding je wilt hebben. Volgens mij kan je inderdaad een encoding "herkennen", maar ik zou niet weten hoe dat zou moeten in Java. Als je een beetje googled moet er wel wat te vinden zijn.

Misschien helpt dit: http://jchardet.sourceforge.net/

[ Voor 13% gewijzigd door grhmpf op 24-07-2005 21:31 ]


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Het is inderdaad stom van me. Ik was eigenlijk tot de conclusie gekomen dat dat encoding attribuut niet zo heel belangrijk was... Maar ik neem aan dat als deze leeg is er UTF-8 wordt gebruikt.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
grhmpf schreef op zondag 24 juli 2005 @ 15:32:
Ja dat had ik wel begrepen. De vraag was hoe je in code die file leest. Ik ga even snel kijken of ik het kan reproduceren :)
Voeg ik de encoding toe:
XML:
1
2
3
4
<?xml version="1.0" encoding="ISO8859-1"?>
<root>
<bla>value met rare tekens &#8218; dat waren ze</bla>
</root>

Dan werkt het al in firefox. Ik geef dus aan dat het bestand ANSI is! Je moet dus geen UTF-8 daar neerzetten want dat gaat niet werken, je karakterset is immers ANSI.
Nee, nogmaals: 128 is een control char in ISO8859-1. Kijk maar op http://www.unicode.org/charts/PDF/U0080.pdf , eerste karakter.

Overigens is "ANSI" de oude naam voor INCITS, het amerikaanse standaardisatie instituut. Hun charset heet ASCII, en is 7-bits (0-127). Een charset "ANSI" is dus verwarrend.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Correct, die encodingnamen had ik wat beter op moeten letten. De encoding moet denk ik CP1252 (die snapt Java in elk geval) of windows-1252 (zie http://www.xml.com/pub/a/2002/09/18/euroxml.html) zijn, ipv ISO8859-1, maar het blijkt dat de parser van FireFox niet moeilijk doet over een 0080 in die charset en er een euro van maakt.

Ik pretendeerde ook niet totaal correct te zijn op zondagmiddag, maar wel een goeie zet in de richting dacht ik :P

Moraal is in elk geval dat je van je xml bestand de encoding moet aangeven zodat ie juist geparsed wordt, hopelijk zijn we het daar wel over eens :)

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ik ben nu weer een stukje verder maar nog niet helemaal waar ik moet zijn. Het parsen gaat in de browsers goed maar in Java gaat er nog iets mis. Ik lees momenteel via een FileInputStream een bestand in naar een Byte[] waarvan via het String object een conversie op doe en deze vervolgens weer via een FileOutputStream weer wegschrijf
code:
1
2
3
4
5
6
7
8
   public byte[] convert(byte[] data, String srcEncoding, String trgtEncoding){
       try{
           String str = new String(data, srcEncoding);
           byte[] result = str.getBytes(trgtEncoding);
           return result;
       }
   catch{}
  }

Maar dit heeft nog niet helemaal het gewenste resultaat. Dit is nl. de output:
code:
1
2
3
4
<?xml version="1.0"?> 
<root>
  <book>Weird characters! €ÂÂ&#8218;</book> 
</root>

Zoals je ziet erg dicht in de buurt maar met  voor de speciale tekens. Bijkomend probleem is dat dit in IE er weer totaal niet uitziet zoals het moet, daar zijn het wederom blokjes...

Edit: Het is mij eindelijk gelukt! Het gaat er dus (zoals al vele malen hier gezegd) om het gebruiken van de juiste encoding. Na eerst "ISO-8859-1" als brond encoding te hebben gebruikt ben ik deze keer voor "Windows-1252" gegaan, en voila!
Ik ben erg blij dat ik het nu voor windows aan de praat heb, maar ik zou toch graag een robuustere oplossing hebben waarbij ik zelf de juiste encoding kan detecteren... Iemand hier nog ideeen over?

[ Voor 21% gewijzigd door Deddiekoel op 25-07-2005 11:28 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Het is fundamenteel onmogelijk om (in Windows) de encoding van een willekeurige text file te detecteren.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Hoe krijg je die files trouwens binnen? Weet je de encoding niet altijd?

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Het is idd mogelijk dat er bronnen van verschillende systemen afkomen. Normaal is het van Windows afkomstig maar het kan ook van Unix komen.

Maar het moet toch mogelijk zijn, want Notepad en Notepad++ (allebei geen Java) doen het ook. Dus het moet wel kunnen, alleen kan het met java?

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Onno
  • Registratie: Juni 1999
  • Niet online
Deddiekoel schreef op maandag 25 juli 2005 @ 13:44:
Maar het moet toch mogelijk zijn, want Notepad en Notepad++ (allebei geen Java) doen het ook.
Je kunt heel globaal wel een aantal dingen gokken, het verschil tussen een ISO-8859 encoding en UTF-16 is bijvoorbeeld meestal wel duidelijk.

Maar je kunt niet zien of iets ISO-8859-1, 2, 3, ... of win-1252, enz. is. Je editor weet immers niet of jij met een bepaalde byte teken A of teken B bedoelt: ¤ en € zijn bijvoorbeeld allebei geldige tekens, en worden in iso-8859-1 resp -15 door dezelfde byte gerepresenteerd. Uit de bytes kun je niet afleiden wat er door de maker mee bedoeld is.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
De globale truc is inderdaad kijken of de file, gezien als een UTF-x encoding begint met de Byte Order Mark. Alle UTF-x encodings zijn zo gekozen dat ze verschillende encodings opleveren van de BOM. Op die manier kun je UTF-7,8,16LE,16BE en 32 onderscheiden. ISO8859-x begint normaal gesproken ook niet met een 0xFF (DEL), dus dat helpt ook al iets. Maar een UTF-8 BOM is niet te onderscheiden van 3 valide ISO8859-x karakters.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1