|
|
Tabulatorzeichen wird nicht gefunden
Letzter Beitrag 06. Feb 2010 10:51 von klaus_b. 6 Antworten.
-
04. Feb 2010 7:15
|
|
-
klaus_b



- Registriert am 28. Jan 2008
- Waldkraiburg
- Beiträge 515
- Punkte 8.420

|
Tabulatorzeichen wird nicht gefunden
Hallo zusammen,
ich bearbeite den HTML Stream der ASP.NET Pipeline in einem HttpResponse Filter. Dabei wird nach gewissen Kriterien das ausgegebene HTML verändert. Zum bearbeiten halte ich das ausgegebene HTML in einer StringBuilder Instanz. Im StringBuilder kann ich eigentlich alle Zeichen finden, mit Ausnahme des Tabulatorzeichen. Es ist zwar vorhanden, da ich den Abstand zwischen den Zeichen sehen kann. Es kann, in der Textansicht der Instanz, auch selektiert und in die Zwischenablage kopiert werden. Jedoch nicht als string \t oder char 9. Beide Möglichkeiten liefern kein Ergebnis. Komischerweise wird der Zeilenumbruch \r\n problemlos erkannt. Somit kann es an der Kodierung eigentlich nicht liegen, oder?!?
Hat jemand eine andere Idee um an das Tabulatorzeichen heran zu kommen?
Servus, Klaus
klaus_b@.NETAlles was an .NET und C# Spass macht, ... oder manchmal auch nicht.
|
|
-
-
-
klaus_b



- Registriert am 28. Jan 2008
- Waldkraiburg
- Beiträge 515
- Punkte 8.420

|
Tabulatorzeichen wird nicht gefunden
Hallo Timo,
die HTML Darstellung ist vollkommen in Ordnung. Mit den StringBuilder hab ich in der Regel keine Probleme, ganz im Gegenteil. Ich steh auf den StringBuilder  Ich kann kein AppendFormat oder ähnliches verwenden, weil der StringBuilder mit dem Inhalt eines Stream in der Write Methode desselben initialisiert wird.
public override void Write(byte[] buffer, int offset, int count)
{
var lf = Environment.NewLine;
var sb = new StringBuilder(Encoding.Default.GetString(buffer));
// jetzt z.B. alle Tabulatorzeichen zwischen zwei Tags entfernen geht nicht
sb.Replace(">\\t<", "><");
// Umbrüche zwischen Tags entfernen geht problemlos
sb.Replace(">" + lf + "<", "><");
// hier weiterer Code
}
Es funktionieren auch Regex-Operationen. Aber eben keine mit Tabulator-Erkennung.
Wenn ich mir aber den Inhalt der StringBuilder Instanz in einer Debugsession ansehe, erkenne ich die Tabulatoren als Abstände zwischen den Buchstaben oder Tags, aber eben nicht als Steuerzeichen \t.
Ich hoffe, ich konnte dir mein Problemchen etwas verdeutlichen.
Servus, Klaus
klaus_b@.NETAlles was an .NET und C# Spass macht, ... oder manchmal auch nicht.
|
|
-
-
Timo Rehl



- Registriert am 05. Mai 2009
- Wald-Michelbach
- Beiträge 291
- Punkte 5.100

|
Tabulatorzeichen wird nicht gefunden
Hallo Klaus, nachdem ich das mal testweise nachimplementiert hab, konnte ich das selbe Phänomen feststellen! Aber ich hab dann doch eine kleine Unstimmigkeit festgestellt, deshalb probier doch mal folgendes: sb.Replace(">\t<", "><");  Aber mal eine andere Frage: wie gehst Du denn damit um, dass Du das Stream-Write aufrufst, und Du letztendlich aber das übergebene "count" ignorierst und weniger in das Endergebnis schreibst? Ich fände eine statische Helfermethode eleganter, die Dir die Ersetzungen vornimmt, anstatt das direkt im Stream in der Write Methode zu machen. Ich kenne einige Anwendungszenarien, da ist man drauf angewiesen von außen nach mehrmaligem "Write" zu wissen, wie viele Bytes nun geschrieben wurden. Grüße Timo
- theres no place like 127.0.0.1 -
|
|
-
-
klaus_b



- Registriert am 28. Jan 2008
- Waldkraiburg
- Beiträge 515
- Punkte 8.420

|
Tabulatorzeichen wird nicht gefunden
Hallo Timo,
Timo Rehl:Aber mal eine andere Frage: wie gehst Du denn damit um, dass Du das Stream-Write aufrufst, und Du letztendlich aber das übergebene "count" ignorierst und weniger in das Endergebnis schreibst?
Die Länge des an die Write-Methode übergebenen byte Array interessiert mich nicht  Ich schreibe das komplette byte Array in die StringBuilder Instanz. Wie groß das Array ist... was soll's  Um die Verwaltung des Stream kümmert sich komplett ASP.NET. Ich mache die Klasse, welche von Stream abgeleitet ist, lediglich als Filter für den HttpResponse in einem Event bekannt. context.Response.Filter = new WhiteSpaceFilter(context.Response.Filter);
Im Event wird der bestehende Stream, also die ASP.NET Pipeline, lediglich durch einen weiteren Filter, also meine Klasse, geschrieben und dabei deren Inhalt verändert. Das ist an und für sich ein sehr gutes Konzept. Vor allem das implementieren von verschiedenen Filtern ist dadurch sehr schön umzusetzen. Nach dem ich den Imhalt umgeschrieben habe, kommt in meinem Fall noch ein GZipStream, der das ganze komprimiert zum Client sendet.
Timo Rehl:Ich fände eine statische Helfermethode eleganter, die Dir die Ersetzungen vornimmt, anstatt das direkt im Stream in der Write Methode zu machen.
Wenn ich alle Problemchen gelöst habe, werde ich eine statische Methode bauen, der ich lediglich das byte Array des Stream übergebe und ein solches auch zurück bekomme. Das zurückgegebene Array schreibe ich dann in den klassen internen Sink, dessen output dann weiter in der ASP.NET Pipeline verarbeitet wird.
Timo Rehl:Ich kenne einige Anwendungszenarien, da ist man drauf angewiesen von außen nach mehrmaligem "Write" zu wissen, wie viele Bytes nun geschrieben wurden.
In der Regel ist das auch so, nur in diesem Fall muss lediglich ASP.NET wissen, an welcher stelle der Stream gerade steht. Ich stelle nur den Stream und verändere die Daten darin.
Servus, Klaus
klaus_b@.NETAlles was an .NET und C# Spass macht, ... oder manchmal auch nicht.
|
|
-
-
-
klaus_b



- Registriert am 28. Jan 2008
- Waldkraiburg
- Beiträge 515
- Punkte 8.420

|
Tabulatorzeichen wird nicht gefunden
Hallo Timo,
Timo Rehl:Ich wollte jetzt nur noch einmal nachfragen, ob Du den kleinen Flüchtigkeitsfehler oben entdeckt und damit dann Dein Problem gelöst hast?
Hab ich gesehen  Den Fehler gibts aber nur im Forum und nicht im Code, da ich den Beitrag hier getippt habe, als ich im Büro war. Da habe ich kein VS, also aus dem Gedächtnis tippen. Das lässt im Alter schon mal ein wenig nach
Timo Rehl:wenn man direkt mit dem Byte-Puffer arbeitet, dann könnte man sogar den StringBuilder umgehen und direkt in den Bytes die Ersetzungen vornehmen
Ich weiß und kenne dieses Vorgehen. Aber... Da wird so dermasen viel ersetzt, unter den unmöglichsten Bedingungen, das die Bearbeitung der bytes die Leistung des Filters ins Bodenlose ziehen würde. Bei der direkten byte Bearbeitung müsste alles in Schleifen mit X Iterationen gelöst werden. Evtl. sogar in geschachtelten Schleifen, was noch einmal eine schlechtere Performance nach sich ziehen würde.
Um die Tabzeichen jetzt zu erkenne gehen ich einen kleinen Umweg. In einer Hilfsmethode, muss ich das byte Array einmal linear durchlaufen und markiere den byte-Wert des Tabzeichens mit einem Wert aus den hohen Bytes der ASCII-Tabelle. Ich habe mich hier für das Zeichen ~ entschieden, weil einmal der Wert mit 126 hoch genung in der Tabelle steht, und zum zweiten ASP.NET dieses Zeichen kennt, selbst verwendet und darstellen kann.
private static byte[] MarkedTabs(byte[] buffer)
{
for (int i = 0; i < buffer.GetLength(0); i++)
{
if (buffer[ i ].Equals(9))
{
buffer[ i ] = 126;
}
}
return buffer;
}
Jetzt kann ich die markierten Zeichen als solche erkennen und bearbeiten. Es funktioniert sogar die markierten Zeichen in der StringBuilder Instanz in echte Tabs \t zu wandeln. So kann ich in manchen Passagen die Tabs behalten und in anderen werden sie ersetzt.
In so fern kann ich mein Problem als gelöst ansehen. Ich danke dir für's mitarbeiten, denn oft hilft es schon wenn man einfach jemanden sein Problem erörtert. Ausserdem ist eine zweite Meinung niemals falsch, vor allem wenn man allein an einem Problem "herumkaut"  Dabei wird man oft blind, und "sieht den Wald vor lauter Bäumen nicht".
Servus, Klaus
klaus_b@.NETAlles was an .NET und C# Spass macht, ... oder manchmal auch nicht.
|
|
Seite 1 von 1 (7 Treffer)
|
|