Najlepszy sposób na usunięcie tagów html z ciągu znaków na serwerze sql?

112

Mam dane w SQL Server 2005, które zawierają tagi HTML i chciałbym to wszystko usunąć, pozostawiając tylko tekst między tagami. Idealnie również zastąpienie rzeczy jak &lt;z <itp

Czy istnieje łatwy sposób na zrobienie tego, czy ktoś ma już przykładowy kod t-sql?

Nie mam możliwości dodawania rozszerzonych składowanych procsów i tym podobnych, więc wolałbym czyste podejście t-sql (najlepiej zgodne wstecz z sql 2000).

Chcę tylko pobrać dane z usuniętym kodem HTML, a nie aktualizować go, więc najlepiej byłoby zapisać je jako funkcję zdefiniowaną przez użytkownika, aby ułatwić ponowne wykorzystanie.

Na przykład konwertowanie tego:

<B>Some useful text</B>&nbsp;
<A onclick="return openInfo(this)"
   href="http://there.com/3ce984e88d0531bac5349"
   target=globalhelp>
   <IMG title="Source Description" height=15 alt="Source Description" 
        src="/ri/new_info.gif" width=15 align=top border=0>
</A>&gt;&nbsp;<b>more text</b></TD></TR>

do tego:

Some useful text > more text
Rory
źródło

Odpowiedzi:

162

Istnieje UDF, który zrobi to opisane tutaj:

Zdefiniowana przez użytkownika funkcja usuwania kodu 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

Edycja: zauważ, że dotyczy to SQL Server 2005, ale jeśli zmienisz słowo kluczowe MAX na około 4000, będzie działać również w SQL Server 2000.

RedFilter
źródło
9
Wielkie dzięki. Komentarze tam odsyłają do ulepszonej wersji: lazycoders.blogspot.com/2007/06/…, która dotyczy większej liczby podmiotów html.
Rory
4
Należy zauważyć, że jako UDF intensywnie wykorzystujący ciągi znaków w SQL Server 2005 lub nowszym jest to doskonały kandydat do implementacji funkcji CLR UDF w celu uzyskania ogromnego wzrostu wydajności. Więcej informacji na ten temat znajdziesz tutaj: stackoverflow.com/questions/34509/…
RedFilter
10
Zauważ, że post lazycoders zawiera dwie literówki. Usuń pojedyncze cudzysłowy z CHAR(13) + CHAR(10)dwóch sekcji, które je zawierają. Wystarczająco subtelny, nie złapałem go, dopóki nie przekroczył długości krótkiego pola (co ciekawe i wymagane dla mnie wszystkie zamienniki są krótsze niż oryginalny ciąg).
goodeye,
1
A co z wartościami zakodowanymi w html? potrzebowałby ich odkodowania. Dzięki.
JDPeckham
2
Użyłem lazycoderów plus poprawka literówki z @goodeye powyżej - działa świetnie. Aby zaoszczędzić czas, wersja bloga lazycoders jest dostępna tutaj: lazycoders.blogspot.com/2007/06/…
qxotk
18

Pochodzi z odpowiedzi @Goner Doug, z kilkoma aktualizacjami:
- użycie REPLACE tam, gdzie to możliwe
- konwersja predefiniowanych jednostek, takich jak &eacute;(wybrałem te, których potrzebowałem :-)
- konwersja tagów list<ul> and <li>

ALTER FUNCTION [dbo].[udf_StripHTML]
--by Patrick Honorez --- www.idevlop.com
--inspired by http://stackoverflow.com/questions/457701/best-way-to-strip-html-tags-from-a-string-in-sql-server/39253602#39253602
(
@HTMLText varchar(MAX)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @Start  int
DECLARE @End    int
DECLARE @Length int

set @HTMLText = replace(@htmlText, '<br>',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<br/>',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<br />',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<li>','- ')
set @HTMLText = replace(@htmlText, '</li>',CHAR(13) + CHAR(10))

set @HTMLText = replace(@htmlText, '&rsquo;' collate Latin1_General_CS_AS, ''''  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&quot;' collate Latin1_General_CS_AS, '"'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&amp;' collate Latin1_General_CS_AS, '&'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&euro;' collate Latin1_General_CS_AS, '€'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&lt;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&gt;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&oelig;' collate Latin1_General_CS_AS, 'oe'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&nbsp;' collate Latin1_General_CS_AS, ' '  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&copy;' collate Latin1_General_CS_AS, '©'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&laquo;' collate Latin1_General_CS_AS, '«'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&reg;' collate Latin1_General_CS_AS, '®'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&plusmn;' collate Latin1_General_CS_AS, '±'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&sup2;' collate Latin1_General_CS_AS, '²'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&sup3;' collate Latin1_General_CS_AS, '³'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&micro;' collate Latin1_General_CS_AS, 'µ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&middot;' collate Latin1_General_CS_AS, '·'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ordm;' collate Latin1_General_CS_AS, 'º'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&raquo;' collate Latin1_General_CS_AS, '»'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac14;' collate Latin1_General_CS_AS, '¼'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac12;' collate Latin1_General_CS_AS, '½'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac34;' collate Latin1_General_CS_AS, '¾'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Aelig' collate Latin1_General_CS_AS, 'Æ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ccedil;' collate Latin1_General_CS_AS, 'Ç'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Egrave;' collate Latin1_General_CS_AS, 'È'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Eacute;' collate Latin1_General_CS_AS, 'É'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ecirc;' collate Latin1_General_CS_AS, 'Ê'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ouml;' collate Latin1_General_CS_AS, 'Ö'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&agrave;' collate Latin1_General_CS_AS, 'à'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&acirc;' collate Latin1_General_CS_AS, 'â'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&auml;' collate Latin1_General_CS_AS, 'ä'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&aelig;' collate Latin1_General_CS_AS, 'æ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ccedil;' collate Latin1_General_CS_AS, 'ç'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&egrave;' collate Latin1_General_CS_AS, 'è'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&eacute;' collate Latin1_General_CS_AS, 'é'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ecirc;' collate Latin1_General_CS_AS, 'ê'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&euml;' collate Latin1_General_CS_AS, 'ë'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&icirc;' collate Latin1_General_CS_AS, 'î'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ocirc;' collate Latin1_General_CS_AS, 'ô'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ouml;' collate Latin1_General_CS_AS, 'ö'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&divide;' collate Latin1_General_CS_AS, '÷'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&oslash;' collate Latin1_General_CS_AS, 'ø'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ugrave;' collate Latin1_General_CS_AS, 'ù'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&uacute;' collate Latin1_General_CS_AS, 'ú'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ucirc;' collate Latin1_General_CS_AS, 'û'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&uuml;' collate Latin1_General_CS_AS, 'ü'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&quot;' collate Latin1_General_CS_AS, '"'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&amp;' collate Latin1_General_CS_AS, '&'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&lsaquo;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&rsaquo;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)


-- Remove anything between <STYLE> tags
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('<', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('</STYLE>', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <whatever> tags
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
Patrick Honorez
źródło
4
Użyłem tego i uwielbiam, ale dodałem jeszcze jedno zastąpienie do górnej grupy: </p> Zmieniłem na znak 13 + znak 10, również ponieważ koniec znacznika akapitu zwykle wskazywałby na nową linię. To zadziałało idealnie w moim konkretnym scenariuszu
DR
1
Ta odpowiedź w większości działała świetnie, ale zakłada się, że wszystkie tagi HTML są prawidłowe. W moim przypadku wystąpił problem z obcinaniem podczas przesyłania VARCHAR, który wyeliminował niektóre tagi zamykające. Prosty PATINDEX RTrim załatwił sprawę, aby usunąć wszystko inne.
matt123788
2
Oprócz zmiany dokonanej przez @DR (plus kilka innych, które wymagały powrotu karetki), przeniosłem również zmiany, które powodują <i >na sam koniec. W przeciwnym razie zostały usunięte z tagami.
a_hardin
8

Jeśli twój HTML jest dobrze sformułowany, myślę, że jest to lepsze rozwiązanie:

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 <i>is</i> an <b>html</b> test')
dudeNumber4
źródło
1
To zadziałało dla mnie. +1. Ale czy mógłbyś wyjaśnić swój kod, aby programiści łatwiej go zrozumieli? :)
Saeed Neamati
wygląda na to, że ładuje html jako dokument xml, a następnie wybiera z niego wszystkie wartości. Uwaga: ten kod rzygnie w & nbsp;
JDPeckham
2
Włam się, żeby nie bombardować kodów HTML. Oczywiście tylko szybki hack do użytku wewnętrznego lub czegokolwiek (tak jak w przypadku akceptowanego UDF).
dudeNumber4
Musi być dobrze uformowany, więc nie jest tak odporny na błędy jak RedFilter.
Micah B.
1
HTML nie jest podzbiorem XML. XHTML tak, ale HTML już nie zmierza tą drogą.
David
7

Oto zaktualizowana wersja tej funkcji, która zawiera odpowiedź RedFilter (oryginał Pinal) z dodatkami LazyCoders i poprawkami literówek goodeye ORAZ mój własny dodatek do obsługi <STYLE>tagów w wierszu wewnątrz HTML.

ALTER FUNCTION [dbo].[udf_StripHTML]
(
@HTMLText varchar(MAX)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @Start  int
DECLARE @End    int
DECLARE @Length int

-- Replace the HTML entity &amp; with the '&' character (this needs to be done first, as
-- '&' might be double encoded as '&amp;amp;')
SET @Start = CHARINDEX('&amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '&')
SET @Start = CHARINDEX('&amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &lt; with the '<' character
SET @Start = CHARINDEX('&lt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '<')
SET @Start = CHARINDEX('&lt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &gt; with the '>' character
SET @Start = CHARINDEX('&gt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '>')
SET @Start = CHARINDEX('&gt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &amp; with the '&' character
SET @Start = CHARINDEX('&amp;amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '&')
SET @Start = CHARINDEX('&amp;amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &nbsp; with the ' ' character
SET @Start = CHARINDEX('&nbsp;', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, ' ')
SET @Start = CHARINDEX('&nbsp;', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1
END

-- Replace any <br> tags with a newline
SET @Start = CHARINDEX('<br>', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br>', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace any <br/> tags with a newline
SET @Start = CHARINDEX('<br/>', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br/>', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace any <br /> tags with a newline
SET @Start = CHARINDEX('<br />', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br />', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <STYLE> tags
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('<', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('</STYLE>', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <whatever> tags
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
Goner Doug
źródło
1
Z mojej informacji, czy jest jakiś powód używania STUFF()zamiast REPLACE()(który byłby bzdury krótszy IMO)?
Patrick Honorez
Tak naprawdę nie myślałem o tym. Po prostu skopiowałem / zmodyfikowałem oryginał, jak wskazano. Zastąpienie może być lepszą opcją. Zastanawiam się, czy jest porównanie wydajności między dwiema funkcjami do rozważenia ...
Goner Doug
1
@GonerDoug wiwatuje, czytał zaakceptowane komentarze, mówiąc, że to naprawdę wymaga aktualizacji.
Jono,
4

To nie jest kompletne nowe rozwiązanie, ale poprawka do rozwiązania anonimowej :

--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)) <> '<BR>') AND (UPPER(SUBSTRING(@HTMLText, @Start, 5)) <> '</BR>')  
    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  
David
źródło
To zadziałało po tym, jak użyłem nvarchar zamiast varchar, ponieważ używam znaków Unicode w tagach html
Shadi Namrouti
3

Spróbuj tego. Jest to zmodyfikowana wersja tej opublikowanej przez RedFilter ... ten SQL usuwa wszystkie tagi oprócz BR, B i P z towarzyszącymi atrybutami:

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)) <> '<BR') AND (UPPER(SUBSTRING(@HTMLText, @Start, 2)) <> '<P') AND (UPPER(SUBSTRING(@HTMLText, @Start, 2)) <> '<B') AND (UPPER(SUBSTRING(@HTMLText, @Start, 3)) <> '</B')
   BEGIN
      SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
   END

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

 RETURN RTRIM(LTRIM(@HTMLText))
END
codeaf
źródło
nie działa dla mnie SELECT dbo.StripHtml ('<b> somestuff </b>'); zwraca dokładnie ten ciąg
ladieu
@ladieu, to jest oczekiwane. Sprawdź pierwszy wiersz odpowiedzi („ten SQL usuwa wszystkie znaczniki z wyjątkiem BR, B i P z towarzyszącymi atrybutami”).
Peter Herdenborg
ta funkcja SQL jest nieprawidłowa. Proszę zapoznać się z odpowiedzią poniżej, aby poznać poprawioną funkcję.
futureelite7
@ futureelite7 używanie „poniżej” i „powyżej” jako odniesienia do tego, gdzie znaleźć odpowiedzi na stronie SO jest bezsensowne, ponieważ kolejność odpowiedzi można zmienić za pomocą zakładek u góry (i więcej, głosowanie może zmienić kolejność odpowiedzi). Proszę podać odpowiedź, podając nazwisko autora, który ją opublikował
Caius Jard
3

Co powiesz na używanie XQuery z jedną linijką:

DECLARE @MalformedXML xml, @StrippedText varchar(max)
SET @MalformedXML = @xml.query('for $x in //. return ($x)//text()')
SET @StrippedText = CAST(@MalformedXML as varchar(max))

To zapętla wszystkie elementy i zwraca tylko tekst ().

Aby uniknąć łączenia tekstu między elementami bez spacji, użyj:

DECLARE @MalformedXML xml, @StrippedText varchar(max)
SET @MalformedXML = @xml.query('for $x in //. return concat((($x)//text())[1]," ")')
SET @StrippedText = CAST(@MalformedXML as varchar(max))

Odpowiadając na pytanie „Jak tego używasz w przypadku kolumny:

  SELECT CAST(html_column.query('for $x in //. return concat((($x)//text()) as varchar(max))
  FROM table

W przypadku powyższego kodu upewnij się, że html_columnjest to typ danych xml, a jeśli nie, musisz zapisać rzutowaną wersję HTML jako xml. Zrobiłbym to jako osobne ćwiczenie podczas ładowania danych HTML, ponieważ SQL wyrzuci błąd, jeśli znajdzie źle sformułowany xml, np. Niedopasowane znaczniki początku / końca, nieprawidłowe znaki.

Są doskonałe do tworzenia fraz wyszukiwania, usuwania kodu HTML itp.

Zwróć uwagę, że zwraca to typ xml, więc CAST lub COVERT do tekstu tam, gdzie to konieczne. Wersja XML tego typu danych jest bezużyteczna, ponieważ nie jest to dobrze sformułowany XML.

Arvin Amir
źródło
Wydaje mi się, że bez rzeczywistego rozwiązania do rzutowania z XML jest to w najlepszym przypadku częściowe rozwiązanie.
Dennis Jaheruddin
CAST (@xml as varchar (max)). Lub CONVERT (xml), @XML). Zakładano, że większość programistów to zrozumie.
Arvin Amir
1
Zdecydowanie rozsądnie jest założyć, że programiści wiedzą, jak przesyłać, ale pamiętaj, że ktoś czytający twoją odpowiedź może nie zobaczyć bezpośrednio, że wystarczy „po prostu” przesyłać. Zwłaszcza, że ​​wspomina się, że możemy rzucać w razie potrzeby . - Nie próbuję być negatywny, mam tylko nadzieję, że pomoże ci to w tworzeniu odpowiedzi, które łatwiej będzie rozpoznać jako użyteczne!
Dennis Jaheruddin
Więc jaką częścią tego jest nazwa kolumny? Powiedzmy, że mam tabelę o nazwie dataz kolumną o nazwie htmli chcę wybrać wszystkie wartości w tej kolumnie, ale usunąć znaczniki HTML, jak mogę użyć Twojej odpowiedzi, aby to osiągnąć?
Felix Eve
2

Oto wersja, która nie wymaga UDF i działa nawet wtedy, gdy kod HTML zawiera tagi bez pasujących tagów zamykających.

TRY_CAST(REPLACE(REPLACE(REPLACE([HtmlCol], '>', '/> '), '</', '<'), '--/>', '-->') AS XML).value('.', 'NVARCHAR(MAX)')
Łaskawy
źródło
1

Chociaż odpowiedź Arvina Amira zbliża się do pełnego rozwiązania jednowierszowego, możesz wpaść wszędzie; ma niewielki błąd w instrukcji select (brakuje końca linii), a ja chciałem poradzić sobie z najczęstszymi odwołaniami do znaków.

Skończyło się na tym, że:

SELECT replace(replace(replace(CAST(CAST(replace([columnNameHere], '&', '&amp;') as xml).query('for $x in //. return concat((($x)//text())[1]," ")') as varchar(max)), '&amp;', '&'), '&nbsp;', ' '), '&#x20;', ' ')
FROM [tableName]

Bez kodu odniesienia znaku można to uprościć do tego:

SELECT CAST(CAST([columnNameHere] as xml).query('for $x in //. return concat((($x)//text())[1]," ")') as varchar(max))
FROM [tableName]
Brian Heward
źródło
0

Kod Patricka Honoreza wymaga niewielkiej zmiany.

Zwraca niepełne wyniki dla html, który zawiera &lt;lub&gt;

Dzieje się tak, ponieważ kod poniżej sekcji

- Usuń wszystko między tagami

w rzeczywistości zamieni <> na nic. Poprawka polega na zastosowaniu dwóch poniższych linii na końcu:

set @HTMLText = replace(@htmlText, '&lt;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&gt;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)
Maghi85
źródło