2016-07-10 15 views
2

Ich habe eine XML-Zeichenfolge in big5 codiert:Wie kann man Nicht-UTF8-XML in Browsern mit Javascript analysieren?

atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iYmlnNSIgPz48dGl0bGU+pKSk5TwvdGl0bGU+') 

(<?xml version="1.0" encoding="big5" ?><title>中文</title> in UTF-8.)

Ich mag würde den Inhalt <title> zu extrahieren. Wie kann ich das mit reinem Javascript in Browsern tun? Bessere leichte Lösungen ohne jQuery oder emscripten.

Haben DOMParser versucht:

(new DOMParser()).parseFromString(atob('PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iYmlnNSIgPz48dGl0bGU+pKSk5TwvdGl0bGU+'), 'text/xml') 

Aber weder Chrom noch Firefox respektiert das Codierungsattribut. Ist es ein Standard, dass DOMParser nur UTF-8 unterstützt?

+0

Vielleicht eine dumme Frage, die meine Unwissenheit aufdeckt, aber wie überprüfen Sie, dass das Kodierungsattribut nicht respektiert wird? –

+0

Auch in Ihrem realen Fall ist die Zeichenfolge als big5 codiert, und dann base64, wie in Ihrem Beispiel hier? –

+0

Als Referenz für zukünftige Besucher sind echte Codes hier: https://github.com/yan12125/chrome_newtab/blob/c2336374c74cce438c956812b7639ed74ede619f/content/newtab.js#L70-L77. Dies ist ein altes Commit meines Projekts, das nun den unten erwähnten TextEncoder verwendet. –

Antwort

2

Ich vermute, dass das Problem nicht DOMParser, aber atob, das, was ursprünglich ein String nicht-ascii war nicht richtig entschlüsseln kann. *

Sie eine andere Methode, um an dem ursprünglichen Bytes verwenden müssen, wie https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js

var encoded = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iYmlnNSIgPz48dGl0bGU+pKSk5TwvdGl0bGU+'; 
var bytes = Base64Binary.decode(encoded); 

und dann einige Verfahren die Bytes umzuwandeln (dekodieren die big5 Daten) in eine Javascript-String verwendet wird.

var decoder = new TextDecoder('big5'); 
var decoded = decoder.decode(bytes); 

Und dann passieren zu DOMParser

var dom = (new DOMParser()).parseFromString(decoded, 'text/xml'); 
var title = dom.children[0].textContent; 

du


* Eine Möglichkeit, zu verstehen, warum bei https://plnkr.co/edit/TBspXlF2vNbNaKq8UxhW?p=preview sehen: Für Firefox/Chrome können Sie TextDecoder verwenden atob nimmt nicht die Kodierung der ursprünglichen Zeichenkette als Parameter, also, während er base64 kodierte Daten zu Bytes intern decodieren muss, muss er m ake eine Annahme auf, welche Zeichencodierung diese Bytes sind, Ihnen dann eine Javascript Zeichenkette zu geben, die ich glaube, wird intern als UTF-16 kodiert.

+0

Danke dafür. TextEncoder/TextDecoder ist tatsächlich das, was ich später benutzt habe. atob ist problematisch, genauso wie DOMParser. In einem Fehlerbericht unter https://bugzilla.mozilla.org/show_bug.cgi?id=1287071 hat ein Mozilla-Entwickler bestätigt, dass DOMParser davon ausgeht, dass alle Eingaben UTF-8 sind. In der Tat von dom/base/DOMParser.cpp von mozilla-central, ist es leicht zu sehen, dass parseFromString eine hartcodierte Codierung UTF-8 verwendet. Der TextDecoder-Ansatz erfordert, dass die Codierung a priori bekannt ist. Es ist weniger als ideal, aber ausreichend für mein Projekt. –

+1

Nur als Referenz, ich denke, es konvertiert intern von UTF-16 zu UTF-8 https://github.com/mozilla/gecko-dev/blob/master/dom/base/DOMParser.cpp#L116. Ich bin mir nicht sicher, ob das für Ihre Situation einen Unterschied macht. –

+0

Danke dafür. Scheint, dass alle Javascript-Zeichenfolgen UTF-16 auf C-Ebene sind? –