scratch/output/Scratch/fr/blog/2010-05-19-How-to-cut-HTML-and-repair-it/index.html

290 lines
13 KiB
HTML
Raw Normal View History

2011-04-20 12:29:01 +00:00
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="keywords" content="arbre, HTML, script, ruby">
<link rel="shortcut icon" type="image/x-icon" href="/Scratch/img/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/Scratch/assets/css/main.css" />
2012-04-02 21:43:39 +00:00
<link rel="stylesheet" type="text/css" href="/Scratch/css/solarized.css" />
<link rel="stylesheet" type="text/css" href="/Scratch/css/idc.css" />
2012-05-02 15:43:56 +00:00
<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
2011-04-20 12:29:01 +00:00
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://feeds.feedburner.com/yannespositocomfr"/>
<link rel="alternate" lang="fr" xml:lang="fr" title="Comment réparer un XML coupé ?" type="text/html" hreflang="fr" href="/Scratch/fr/blog/2010-05-19-How-to-cut-HTML-and-repair-it/" />
<link rel="alternate" lang="en" xml:lang="en" title="How to repair a cutted XML?" type="text/html" hreflang="en" href="/Scratch/en/blog/2010-05-19-How-to-cut-HTML-and-repair-it/" />
<script type="text/javascript" src="/Scratch/js/jquery-1.3.1.min.js"></script>
<script type="text/javascript" src="/Scratch/js/jquery.cookie.js"></script>
<script type="text/javascript" src="/Scratch/js/index.js"></script>
2012-05-02 15:43:56 +00:00
<script type="text/javascript" src="/Scratch/js/highlight/highlight.pack.js"></script>
<script type="text/javascript" src="/Scratch/js/article.js"></script>
2011-04-20 12:29:01 +00:00
<!--[if lt IE 9]>
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->
<title>Comment réparer un XML coupé ?</title>
</head>
2011-10-18 22:30:00 +00:00
<body lang="fr" class="article">
2011-04-20 12:29:01 +00:00
<script type="text/javascript">// <![CDATA[
document.write('<div id="blackpage"><img src="/Scratch/img/loading.gif" alt="Chargement en cours..."/></div>');
2011-04-20 12:29:01 +00:00
// ]]>
</script>
<div id="content">
<div id="choix">
<div class="return"><a href="#entete">&darr; Menu &darr;</a></div>
<div id="choixlang">
<a href="/Scratch/en/blog/2010-05-19-How-to-cut-HTML-and-repair-it/" onclick="setLanguage('en')">in English</a>
2011-04-20 12:29:01 +00:00
</div>
2011-09-28 16:05:55 +00:00
<div class="flush"></div>
2011-04-20 12:29:01 +00:00
</div>
<div id="titre">
<h1>
Comment réparer un XML coupé ?
</h1>
<h2>
et comment s'en sortir sans parseur ?
</h2>
</div>
<div class="flush"></div>
<div class="flush"></div>
<div id="afterheader">
<div class="corps">
2012-05-02 15:43:56 +00:00
<p>Sur ma page daccueil vous pouvez voir la liste des mes derniers articles avec le début de ceux-ci. Pour arriver à faire ça, jai besoin de couper le code XHTML de mes pages en plein milieu. Il ma donc fallu trouver un moyen de les réparer.</p>
2011-04-20 12:29:01 +00:00
<p>Prenons un exemple&nbsp;:</p>
2012-05-02 15:43:56 +00:00
<pre><code class="html">&lt;div class="corps"&gt;
&lt;div class="intro"&gt;
&lt;p&gt;Introduction&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The first paragraph&lt;/p&gt;
&lt;img src="/img/img.png" alt="an image"/&gt;
&lt;p&gt;Another long paragraph&lt;/p&gt;
&lt;/div&gt;
</code></pre>
<p>Après avoir coupé, jobtiens&nbsp;:</p>
<pre><code class="html">&lt;div class="corps"&gt;
&lt;div class="intro"&gt;
&lt;p&gt;Introduction&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The first paragraph&lt;/p&gt;
&lt;img src="/img/im
</code></pre>
<p>En plein milieu dun tag <code>&lt;img&gt;</code>&nbsp;!</p>
<p>En réalité, ce nest pas si difficile que celà peut paraître au premier abord. Le secret réside dans le fait de comprendre que lon na pas besoin de conserver la structure complète de larbre pour le réparer, mais seulement la liste des parents non fermés.</p>
<p>Pour notre exemple, juste après le paragraphe <code>first paragraph</code> nous navons quà fermer un <code>div</code> pour la classe <code>corps</code> et le XML est réparé. Bien entendu, quand on est dans le cas où un tag est coupé au milieu, on a quà remonté juste avant le début de ce tag corrompu.</p>
<p>Donc, tout ce que nous avons à faire, cest denregistrer la liste des parents dans une pile. Supposons que nous traitions le premier exemple complètement. La pile passera par les états suivants&nbsp;:</p>
<pre><code class="html">[]
[div] &lt;div class="corps"&gt;
[div, div] &lt;div class="intro"&gt;
[div, div, p] &lt;p&gt;
2011-04-20 12:29:01 +00:00
Introduction
2012-05-02 15:43:56 +00:00
[div, div] &lt;/p&gt;
[div] &lt;/div&gt;
[div, p] &lt;p&gt;
2011-04-20 12:29:01 +00:00
The first paragraph
2012-05-02 15:43:56 +00:00
[div] &lt;/p&gt;
[div] &lt;img src="/img/img.png" alt="an image"/&gt;
[div, p] &lt;p&gt;
2011-04-20 12:29:01 +00:00
Another long paragraph
2012-05-02 15:43:56 +00:00
[div] &lt;/p&gt;
[] &lt;/div&gt;
</code></pre>
<p>Lalgorithme est alors très simple&nbsp;:</p>
2011-04-20 12:29:01 +00:00
2012-05-02 15:43:56 +00:00
<pre><code class="html">let res be the XML as a string ;
2011-04-20 12:29:01 +00:00
read res and each time you encouter a tag:
if it is an opening one:
push it to the stack
else if it is a closing one:
2012-05-02 15:43:56 +00:00
pop the stack.
2011-04-20 12:29:01 +00:00
2012-05-02 15:43:56 +00:00
remove any malformed/cutted tag in the end of res
2011-04-20 12:29:01 +00:00
for each tag in the stack, pop it, and write:
2012-05-02 15:43:56 +00:00
res = res + closed tag
2011-04-20 12:29:01 +00:00
2012-05-02 15:43:56 +00:00
return res
</code></pre>
2011-04-20 12:29:01 +00:00
<p>Et <code>res</code> contiend le XML réparé.</p>
2012-05-02 15:43:56 +00:00
<p>Finallement, voici le code en ruby que jutilise. La variable <code>xml</code> contient le XML coupé.</p>
<div class="codefile"><a href="/Scratch/fr/blog/2010-05-19-How-to-cut-HTML-and-repair-it/code/repair_xml.rb">&#x27A5; repair_xml.rb</a></div>
<pre><code class="ruby"># repair cutted XML code by closing the tags
# work even if the XML is cut into a tag.
# example:
# transform '&lt;div&gt; &lt;span&gt; toto &lt;/span&gt; &lt;p&gt; hello &lt;a href="http://tur'
# into '&lt;div&gt; &lt;span&gt; toto &lt;/span&gt; &lt;p&gt; hello &lt;/p&gt;&lt;/div&gt;'
def repair_xml( xml )
parents=[]
depth=0
xml.scan( %r{&lt;(/?)(\w*)[^&gt;]*(/?)&gt;} ).each do |m|
if m[2] == "/"
next
end
if m[0] == ""
parents[depth]=m[1]
depth+=1
else
depth-=1
end
end
res=xml.sub(/&lt;[^&gt;]*$/m,'')
depth-=1
depth.downto(0).each { |x| res&lt;&lt;= %{&lt;/#{parents[x]}&gt;} }
2011-04-20 12:29:01 +00:00
res
2012-05-02 15:43:56 +00:00
end
</code></pre>
2011-04-20 12:29:01 +00:00
2012-05-02 15:43:56 +00:00
<p>Je ne sais pas si ce code pourra vous être utile. Par contre le raisonnement pour y parvenir mérite dêtre connu.</p>
2011-04-20 12:29:01 +00:00
</div>
2012-04-10 13:56:34 +00:00
<div id="social">
<div class="left"> <a href="https://twitter.com/share" class="twitter-share-button" data-via="yogsototh">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<div class="left"> <div class="g-plusone" data-size="medium" data-annotation="inline" data-width="106"></div>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</div>
<div class="flush"></div>
</div>
2011-04-20 12:29:01 +00:00
<div id="choixrss">
<a id="rss" href="http://feeds.feedburner.com/yannespositocomfr">
s'abonner
</a>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#comment').hide();
$('#clickcomment').click(showComments);
});
function showComments() {
$('#comment').show();
$('#clickcomment').fadeOut();
}
2012-04-10 13:56:34 +00:00
document.write('<div id="clickcomment">Commentaires &amp; Partage</div>');
2011-04-20 12:29:01 +00:00
</script>
<div class="flush"></div>
2012-04-10 13:56:34 +00:00
2011-04-20 12:29:01 +00:00
<div class="corps" id="comment">
<h2 class="first">commentaires</h2>
<noscript>
Vous devez activer javascript pour commenter.
</noscript>
<script type="text/javascript">
var idcomments_acct = 'a307f0044511ff1b5cfca573fc0a52e7';
var idcomments_post_id = '/Scratch/fr/blog/2010-05-19-How-to-cut-HTML-and-repair-it/';
var idcomments_post_url = 'http://yannesposito.com/Scratch/fr/blog/2010-05-19-How-to-cut-HTML-and-repair-it/';
2011-04-20 12:29:01 +00:00
</script>
<span id="IDCommentsPostTitle" style="display:none"></span>
<script type='text/javascript' src='/Scratch/js/genericCommentWrapperV2.js'></script>
2011-04-20 12:29:01 +00:00
</div>
<div id="entete" class="corps_spaced">
<div id="liens">
<ul><li><a href="/Scratch/fr/">Bienvenue</a></li>
<li><a href="/Scratch/fr/blog/">Blog</a></li>
<li><a href="/Scratch/fr/softwares/">Softwares</a></li>
<li><a href="/Scratch/fr/about/">À propos</a></li></ul>
2011-04-20 12:29:01 +00:00
</div>
<div class="flush"></div>
<hr/>
<div id="next_before_articles">
<div id="previous_articles">
articles précédents
<div class="previous_article">
<a href="/Scratch/fr/blog/2010-05-17-at-least-this-blog-revive/"><span class="nicer">«</span>&nbsp;Je reviens à la vie !</a>
2011-04-20 12:29:01 +00:00
</div>
2012-04-02 21:43:39 +00:00
<div class="previous_article">
<a href="/Scratch/fr/blog/2010-03-23-Encapsulate-git/"><span class="nicer">«</span>&nbsp;Encapsuler git</a>
</div>
<div class="previous_article">
<a href="/Scratch/fr/blog/2010-03-22-Git-Tips/"><span class="nicer">«</span>&nbsp;Astuces Git</a>
</div>
2011-04-20 12:29:01 +00:00
</div>
<div id="next_articles">
articles suivants
<div class="next_article">
2012-04-02 21:43:39 +00:00
<a href="/Scratch/fr/blog/2010-05-24-Trees--Pragmatism-and-Formalism/">Arbres ; Pragmatisme et Formalisme&nbsp;<span class="nicer">»</span></a>
2011-04-20 12:29:01 +00:00
</div>
<div class="next_article">
2012-04-02 21:43:39 +00:00
<a href="/Scratch/fr/blog/2010-06-14-multi-language-choices/">choix liés à l'écriture dans plusieurs langues&nbsp;<span class="nicer">»</span></a>
2011-04-20 12:29:01 +00:00
</div>
2012-04-02 21:43:39 +00:00
<div class="next_article">
<a href="/Scratch/fr/blog/2010-06-15-Get-my-blog-engine/">Récupérez mon système de blog&nbsp;<span class="nicer">»</span></a>
</div>
2011-04-20 12:29:01 +00:00
</div>
<div class="flush"></div>
</div>
</div>
<div id="bottom">
2012-04-02 21:43:39 +00:00
<div>
2012-04-10 13:56:34 +00:00
<a href="https://twitter.com/yogsototh">Follow @yogsototh</a>
2012-04-02 21:43:39 +00:00
</div>
2011-04-20 12:29:01 +00:00
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.fr">Droits de reproduction ©, Yann Esposito</a>
</div>
<div id="lastmod">
Écrit le : 19/05/2010
modifié le : 04/10/2010
</div>
<div>
Site entièrement réalisé avec
<a href="http://www.vim.org">Vim</a>
et
<a href="http://nanoc.stoneship.org">nanoc</a>
</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>