Thread HTML::Parser - Attribute von HTML ändern, welche sich nicht(!) unterhalb <pre> oder <code> befinden
(21 answers)
Opened by GwenDragon at 2023-01-30 18:12
Gibt es eine Möglichkeit bei HTML::Parser die Kind-Elemente de Eltern-Elemente <CODE> und <PRE> unverändert auszugeben?
HTML::Parser ist immer so eine komplizierte Sache. Meine Lösung (oder geht's noch einfacher oder robuster?): Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 #!/usr/bin/perl use strict; use warnings; use 5.024; use utf8; use HTML::Parser; use URI; my $current_uri = "https://example.org/tests/" ; # enthält aktuelle URL (notwendig für relative URLs) my $source = <<'HTML'; <ul> <li><a href="." title="Anfang">Test</a> <li><a href="test.html" title="Erster Test" class="c1">Test 1</a> <li><a href="Test1/test.html">Test 2</a> <li><a href="http://example.org/example/Test1/test.html">Test 3</a> <li><a href="//example.org/example/Test1/test.html">Test 4</a> <li><a href="./example/Test1/test.html">Test 5</a> <li><a href="./example/.././../../Test1/test.html">Test 6</a> <li><a href="a/s/d/f/g/h/j//test.html">Test 7</a> </ul> <?php # auch hier nix ändern # <a href="test.html" title="Erster Test" class="c1">Test 1</a> ?> <!-- Kommentarblock; auch hier nix ändern!!!! <ul> <li><a href="." title="Anfang">Test</a> <li><a href="test.html" title="Erster Test" class="c1">Test 1</a> <li><a href="Test1/test.html">Test 2</a> <li><a href="http://example.org/example/Test1/test.html">Test 3</a> <li><a href="//example.org/example/Test1/test.html">Test 4</a> <li><a href="./example/Test1/test.html">Test 5</a> <li><a href="./example/.././../../Test1/test.html">Test 6</a> <li><a href="a/s/d/f/g/h/j//test.html">Test 7</a> </ul> --> <pre><code> <!-- Hier im PRE oder CODE-Kindern erst recht niemals was ändern!!!! --> <ul> <li><a href=".">Test</a> <li><a href="test.html">Test 1</a> <li><a href="Test1/test.html">Test 2</a> <li><a href="http://example.org/example/Test1/test.html">Test 3</a> <li><a href="//example.org/example/Test1/test.html">Test 4</a> <li><a href="./example/Test1/test.html">Test 5</a> <li><a href="./example/.././../../Test1/test.html">Test 6</a> <li><a href="a/s/d/f/g/h/j//test.html">Test 7</a> </ul> </code></pre> HTML ### Hier kommt der Parser { # HTML-Parser erzeugen my $p = HTML::Parser->new(); $p->empty_element_tags( 1 ); # Handlerroutine für bestimmte Startelemente registrieren $p->handler( start => \&start, "tagname,attr,self" ); # Handlerroutine für normalen Textinhalt registrieren $p->handler( text => sub { print shift }, "dtext,self" ); # Kommentare $p->handler( comment => sub { print shift }, "text" ); # PHP oder anderes $p->handler( process => sub { print shift }, "text" ); # HTML scannen $p->parse( $source ); # Parsen beenden $p->eof; # Handler für HTML-Startelemente sub start { my ( $tag, $attr, $self ) = @_; # HTML-Element <PRE> if ( lc $tag eq "pre" ) { $self->handler( start => sub { print shift }, 'text' ); $self->handler( end => \&end, "tagname,self" ); } # <CODE>-Block if ( lc $tag eq "code" ) { $self->handler( start => sub { print shift }, 'text' ); $self->handler( end => \&end, "tagname,self" ); } # <A> HTML-Element a, ein Link if ( lc $tag eq "a" ) { $self->handler( end => \&end, "tagname,self" ); # URLs in RFC-gültige URI umwandeln local $URI::ABS_REMOTE_LEADING_DOTS = 1; $attr->{ href } = URI->new( $attr->{ href } )->abs( $current_uri ); } # andere HTML Elemente wieder ausgeben (samt Attributen!) print "<$tag"; # zum HTML-Element Attribute und Werte ausgeben while ( my ( $att, $val ) = each %{ $attr } ) { print qq/ $att="$val"/; } print ">"; } ## end sub start # Handler für HTML-Endelemente sub end { my ( $tag, $self ) = @_; # HTML-Endelement ausgeben print "</$tag>"; } } Ergibt das dann: Code: (dl
)
1 <ul> Lösung sieht sauber aus, aber ich frage euch trotzdem mal, vielleicht überseh’ ich was beim Parsen des HTML. Mist, kaum ist da so ein Schnippsel im HTML: Code: (dl
)
1 <?php dann erzeugt den Schnippsel: Code: (dl
)
1 <?php Seltsam, warum schlug das denn beim obigen Code nicht an? Ich hachte Zeile 76 fängt das ab? Last edited: 2023-02-01 12:20:00 +0100 (CET) |