134 votes

Comment supprimer les balises HTML d'une chaîne dans SQL Server?

J'ai des données dans SQL Server 2005 qui contiennent des balises HTML et je voudrais tout enlever, ne laissant que le texte entre les balises. Idéalement, en remplaçant également des choses comme < par <, etc.

Y a-t-il un moyen simple de le faire ou quelqu'un a-t-il déjà un exemple de code T-SQL?

Je n'ai pas la possibilité d'ajouter des procédures stockées étendues et similaires, donc je préférerais une approche pure T-SQL (de préférence rétrocompatible avec SQL 2000).

Je veux juste récupérer les données avec les balises HTML supprimées, sans les mettre à jour, donc idéalement cela serait écrit sous forme de fonction définie par l'utilisateur, pour faciliter la réutilisation.

Donc par exemple, en convertissant ceci:

Some useful text 

> more text

en ceci:

Some useful text > more text

185voto

RedFilter Points 84190

Il existe une UDF qui fera cela décrite ici :

Fonction définie par l'utilisateur pour supprimer le HTML

CREATE FUNCTION [dbo].[udf_StripHTML] (@HTMLText VARCHAR(MAX))
RETURNS VARCHAR(MAX) AS
BEGIN
    DECLARE @Start INT
    DECLARE @End INT
    DECLARE @Length INT
    SET @Start = CHARINDEX('<',@HTMLText)
    SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
    SET @Length = (@End - @Start) + 1
    WHILE @Start > 0 AND @End > 0 AND @Length > 0
    BEGIN
        SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
        SET @Start = CHARINDEX('<',@HTMLText)
        SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
        SET @Length = (@End - @Start) + 1
    END
    RETURN LTRIM(RTRIM(@HTMLText))
END
GO

Éditer : notez que cela concerne SQL Server 2005, mais si vous changez le mot clé MAX par quelque chose comme 4000, cela fonctionnera également dans SQL Server 2000.

10 votes

Génial, merci. Les commentaires renvoient vers une version améliorée : lazycoders.blogspot.com/2007/06/… qui traite davantage d'entités HTML.

4 votes

Notez que, en tant qu'UDF intensif en chaînes dans SQL Server 2005 ou ultérieur, ceci est un candidat idéal pour implémenter une fonction CLR UDF pour un important renforcement des performances. Plus d'informations à ce sujet ici: stackoverflow.com/questions/34509/…

11 votes

Remarque : le post de lazycoders contient deux fautes de frappe. Supprimez les guillemets simples autour de CHAR(13) + CHAR(10) dans deux des sections qui les contiennent. Assez subtile pour que je ne le remarque pas jusqu'à ce que cela dépasse la longueur d'un champ court (de manière intéressante, et nécessaire pour moi, toutes les substitutions sont plus courtes que la chaîne d'origine).

10voto

dudeNumber4 Points 873

Si votre HTML est bien formé, je pense que c'est une meilleure solution :

create function dbo.StripHTML( @text varchar(max) ) returns varchar(max) as
begin
    declare @textXML xml
    declare @result varchar(max)
    set @textXML = REPLACE( @text, '&', '' );
    with doc(contents) as
    (
        select chunks.chunk.query('.') from @textXML.nodes('/') as chunks(chunk)
    )
    select @result = contents.value('.', 'varchar(max)') from doc
    return @result
end
go

select dbo.StripHTML('This is an html test')

1 votes

Cela a fonctionné pour moi. +1. Mais pourriez-vous expliquer votre code, afin que les développeurs le comprennent plus facilement ? :)

0 votes

Il semble charger le html en tant que document xml, puis sélectionne toutes les valeurs de celui-ci. Remarque : ce code renvoie une erreur avec

2 votes

Mettez un hack pour ne pas planter sur les codes HTML. Évidemment, juste un hack rapide pour un usage interne ou autre (tout comme avec UDF accepté).

4voto

David Points 11

Ce n'est pas une nouvelle solution complète mais une correction pour la solution de afwebservant :

--note comments to see the corrections

CREATE FUNCTION [dbo].[StripHTML] (@HTMLText VARCHAR(MAX))  
RETURNS VARCHAR(MAX)  
AS  
BEGIN  
 DECLARE @Start  INT  
 DECLARE @End    INT  
 DECLARE @Length INT  
 --DECLARE @TempStr varchar(255) (this is not used)  

 SET @Start = CHARINDEX('<',@HTMLText)  
 SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))  
 SET @Length = (@End - @Start) + 1  

 WHILE @Start > 0 AND @End > 0 AND @Length > 0  
 BEGIN  
   IF (UPPER(SUBSTRING(@HTMLText, @Start, 4)) <> '') AND (UPPER(SUBSTRING(@HTMLText, @Start, 5)) <> '')  
    begin  
      SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')  
      end  
-- this ELSE and SET is important
   ELSE  
      SET @Length = 0;  

-- minus @Length here below is important
   SET @Start = CHARINDEX('<',@HTMLText, @End-@Length)  
   SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText, @Start))  
-- instead of -1 it should be +1
   SET @Length = (@End - @Start) + 1  
 END  

 RETURN RTRIM(LTRIM(@HTMLText))  
END

0 votes

Cela a fonctionné pour moi après avoir utilisé nvarchar au lieu de varchar car j'utilise des caractères unicode à l'intérieur des balises html

3voto

afwebservant Points 41

Essayez ceci. C'est une version modifiée de celle postée par RedFilter ... cet SQL supprime toutes les balises sauf BR, B et P avec leurs éventuels attributs :

CREATE FUNCTION [dbo].[StripHtml] (@HTMLText VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
 DECLARE @Start  INT
 DECLARE @End    INT
 DECLARE @Length INT
 DECLARE @TempStr varchar(255)

 SET @Start = CHARINDEX('<',@HTMLText)
 SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
 SET @Length = (@End - @Start) + 1

 WHILE @Start > 0 AND @End > 0 AND @Length > 0
 BEGIN
   IF (UPPER(SUBSTRING(@HTMLText, @Start, 3)) <> ' ' ' '',@HTMLText,CHARINDEX('<',@HTMLText, @Start))
   SET @Length = (@End - @Start) - 1
 END

 RETURN RTRIM(LTRIM(@HTMLText))
END

0 votes

N'a pas fonctionné pour moi SELECT dbo.StripHtml('somestuff'); retourne cette chaîne exacte

0 votes

@ladieu, c'est prévu. Vérifiez la toute première ligne de la réponse ("ce SQL supprime toutes les balises sauf BR, B et P avec leurs éventuels attributs").

0 votes

Cette fonction SQL est incorrecte. Veuillez vous référer à la réponse ci-dessous pour la fonction corrigée.

1voto

Ian Points 11

J'ai eu la 'version améliorée' de ici déjà mentionnée par Rory.

Je ne sais pas si c'est spécifique à SQL 2008 R2, mais le < ne fonctionnait pas, le code HTML strippé s'arrêtait juste là.

La solution était simplement de faire du 'moins que' le dernier élément du code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X