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>"; } }
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
<ul>
<li><a href="https://example.org/tests/" title="Anfang">Test</a>
<li><a class="c1" href="https://example.org/tests/test.html" title="Erster Test">Test 1</a>
<li><a href="https://example.org/tests/Test1/test.html">Test 2</a>
<li><a href="http://example.org/example/Test1/test.html">Test 3</a>
<li><a href="https://example.org/example/Test1/test.html">Test 4</a>
<li><a href="https://example.org/tests/example/Test1/test.html">Test 5</a>
<li><a href="https://example.org/Test1/test.html">Test 6</a>
<li><a href="https://example.org/tests/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>
1
2
3
4
5
6
7
8
9
<?php
# auch hier nix ändern
# <a href="test.html" title="Erster Test" class="c1">Test 1</a>
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
<?
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
1
2
3
4
5
6
7
8
9
<?php
# auch hier nix õndern
# <a href="test.html" title="Erster Test" class="c1">Test 1</a>
echo "<a title="Erster Test" class="c1" href="https://example.org/tests/test.html">Test 1</a>";
?>
<?
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
2023-01-30T17:12:57 GwenDragonMist, kaum ist da so ein Schnippsel im HTML:
Code: (dl )1
2
3
4
5
6
7
8
9<?php
# auch hier nix ändern
# <a href="test.html" title="Erster Test" class="c1">Test 1</a>
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
<?
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
dann erzeugt den Schnippsel:
Code: (dl )1
2
3
4
5
6
7
8
9<?php
# auch hier nix õndern
# <a href="test.html" title="Erster Test" class="c1">Test 1</a>
echo "<a title="Erster Test" class="c1" href="https://example.org/tests/test.html">Test 1</a>";
?>
<?
echo "<a href="test.html" title="Erster Test" class="c1">Test 1</a>";
?>
Seltsam, warum schlug das denn beim obigen Code nicht an?
Ich hachte Zeile 76 fängt das ab?
$p->xml_pic( 1 );
Quote$p->xml_pic( 1 );
1 2
# Handlerroutine für normalen Textinhalt registrieren $p->handler( text => sub { print shift }, "dtext,self" );
1
2
3
4
5
<%
#TEST
<a href="test.html" title="Erster Test" class="c1">Test 1</a>
%>
<%= $header %>
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
use HTML::Parser; use URI; sub replace_with_absolute_uri { # Parameter: # $source: HTML als Zeichenkette # $current_uri: $current_uri: absoluter URI als Ziel # Returns # geändertes HTML als String my $source = shift; my $current_uri = shift; # Puffer für geänderte Elemente my @replaced_data = (); # Variablen für Handler der Start-/Endelemente des HTML my ( $mystart, $myend ); # Handler HTML-Startelemente $mystart = sub { my ( $tag, $attr, $self ) = @_; # HTML-Element <PRE>unverändert ausgeben if ( lc $tag eq "pre" ) { $self->handler( start => sub { my $s = shift; push @replaced_data, $s; }, 'text' ); $self->handler( end => $myend, "tagname,self" ); } # HTML-Element <CODE>, Code-Blocks unverändert ausgeben if ( lc $tag eq "code" ) { $self->handler( start => sub { my $s = shift; push @replaced_data, $s; }, 'text' ); $self->handler( end => $myend, "tagname,self" ); } # HTML-Element <A>, ein Link if ( lc $tag eq "a" ) { $self->handler( end => $myend, "tagname,self" ); # URLs in RFC-gültige absolute URI umwandeln local $URI::ABS_REMOTE_LEADING_DOTS = 1; $attr->{ href } = URI->new( $attr->{ href } )->abs( $current_uri ) if exists $attr->{ href }; } local $URI::ABS_REMOTE_LEADING_DOTS = 1; # auch Attribut src, falls esistent! bei anderen HTML-Elemente auf absolute URI ändern $attr->{ src } = URI->new( $attr->{ src } )->abs( $current_uri ) if exists $attr->{ src }; # andere HTML Elemente wieder ausgeben (samt Attributen!) push @replaced_data, "<$tag"; # zum HTML-Element Attribute und Werte ausgeben while ( my ( $att, $val ) = each %{ $attr } ) { push @replaced_data, qq/ $att="$val"/; } push @replaced_data, ">"; }; ## end sub start # Handler HTML-Endelemente $myend = sub { my ( $tag, $self ) = @_; # HTML-Endelement ausgeben push @replaced_data, "</$tag>"; }; # HTML-Parser erzeugen my $p = HTML::Parser->new(); $p->empty_element_tags( 1 ); $p->xml_pic( 1 ); # damit auch z.B. <?php .... ?> geparst wird # Handlerroutine für bestimmte Startelemente registrieren $p->handler( start => $mystart, "tagname,attr,self" ); # Handlerroutine für bestimmte Endelemente registrieren $p->handler( end => $myend, "tagname,self" ); # Handlerroutine für normalen Textinhalt registrieren $p->handler( text => sub { my $s = shift; push @replaced_data, $s; }, "text" ); # Handlerroutine für Kommentare registrieren $p->handler( comment => sub { my $s = shift; push @replaced_data, $s; }, "text" ); # Handlerroutine für PHP und anderes mit <? ?> $p->handler( process => sub { my $s = shift; push @replaced_data, $s; }, "text" ); # HTML nun parsen und ändern $p->parse( $source ); return join "", @replaced_data; } ## end sub replace_with_absolute_uri