Cara terbaik untuk menghapus tag html dari string di server sql?

112

Saya punya data di SQL Server 2005 yang berisi tag html dan saya ingin menghapus semua itu, meninggalkan hanya teks di antara tag. Idealnya juga mengganti hal-hal seperti &lt;dengan< , dll.

Apakah ada cara mudah untuk melakukan ini atau apakah seseorang sudah mendapatkan beberapa contoh kode t-sql?

Saya tidak memiliki kemampuan untuk menambahkan procs tersimpan yang diperpanjang dan sejenisnya, jadi saya lebih memilih pendekatan t-sql murni (lebih disukai yang kompatibel dengan sql 2000).

Saya hanya ingin mengambil data dengan html yang telah dilucuti, bukan memperbaruinya, jadi idealnya itu akan ditulis sebagai fungsi yang ditentukan pengguna, agar mudah digunakan kembali.

Jadi misalnya mengubah ini:

<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>

untuk ini:

Some useful text > more text
Rory
sumber

Jawaban:

162

Ada UDF yang akan melakukan itu yang dijelaskan di sini:

Fungsi Buatan Pengguna untuk Menghapus 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

Edit: catat ini untuk SQL Server 2005, tetapi jika Anda mengubah kata kunci MAX menjadi 4000, ini akan berfungsi di SQL Server 2000 juga.

RedFilter
sumber
9
Terima kasih banyak. Komentar di sana tertaut ke versi yang ditingkatkan: lazycoders.blogspot.com/2007/06/… yang berhubungan dengan lebih banyak entitas html.
Rory
4
Perhatikan bahwa sebagai UDF intensif string di SQL Server 2005 atau yang lebih baru, ini adalah kandidat yang sempurna untuk menerapkan fungsi UDF CLR untuk peningkatan kinerja yang besar. Info lebih lanjut tentang melakukannya di sini: stackoverflow.com/questions/34509/…
RedFilter
10
Perhatikan posting lazycoders memiliki dua kesalahan ketik. Hapus tanda kutip tunggal dari sekitar CHAR(13) + CHAR(10)dalam dua bagian yang memiliki ini. Cukup halus saya tidak menangkapnya sampai melebihi panjang bidang pendek (menarik, dan diperlukan bagi saya, semua penggantian lebih pendek dari string aslinya).
selamat tinggal
1
Bagaimana dengan nilai yang dikodekan html? akan membutuhkannya diterjemahkan. Terima kasih.
JDPeckham
2
Saya menggunakan lazycoders, ditambah perbaikan kesalahan ketik dari @goodeye di atas - berfungsi dengan baik. Untuk menghemat waktu, versi blog lazycoders ada di sini: lazycoders.blogspot.com/2007/06/…
qxotk
18

Berasal dari jawaban @Goner Doug, dengan beberapa hal yang diperbarui:
- menggunakan REPLACE jika memungkinkan
- konversi entitas yang telah ditentukan sebelumnya seperti &eacute;(saya memilih yang saya butuhkan :-)
- beberapa konversi tag daftar<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
sumber
4
Saya telah menggunakan ini dan menyukainya, tetapi saya menambahkan satu penggantian lagi ke grup teratas: </p> Saya mengubah ke karakter 13 + karakter 10 juga karena akhir dari tag paragraf biasanya akan menunjukkan baris baru. Ini bekerja dengan sempurna dalam skenario khusus saya
DR
1
Jawaban ini berfungsi dengan baik untuk sebagian besar, tetapi ada asumsi bahwa semua tag HTML Anda valid. Dalam kasus saya, ada masalah pemotongan pada unggahan VARCHAR yang menghilangkan beberapa tag penutup. PATINDEX RTrim sederhana melakukan trik untuk menghapus yang lainnya.
matt123788
2
Selain perubahan yang dibuat @DR (ditambah beberapa lagi yang membutuhkan pengembalian kereta), saya juga memindahkan penggantian yang menghasilkan <dan >sampai akhir. Jika tidak, mereka akan dihapus dengan tag.
a_hardin
8

Jika HTML Anda terbentuk dengan baik, saya pikir ini adalah solusi yang lebih baik:

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
sumber
1
Ini berhasil untuk saya. +1. Tapi bisakah Anda menjelaskan kode Anda, sehingga pengembang lebih mudah memahaminya? :)
Saeed Neamati
sepertinya itu memuat html sebagai dokumen xml lalu memilih semua nilai darinya. Catatan: kode ini muncul di & nbsp;
JDPeckham
2
Lakukan peretasan agar tidak membom kode HTML. Jelas hanya retasan cepat untuk penggunaan di rumah atau apa pun (seperti dengan UDF yang diterima).
dudeNumber4
Itu harus dibentuk dengan baik, jadi itu tidak toleran terhadap kesalahan seperti RedFilter.
Mikha B.
1
HTML bukan bagian dari XML. XHTML, tetapi HTML tidak mengarah ke jalan itu lagi.
David
7

Berikut adalah versi terbaru dari fungsi ini yang menggabungkan jawaban RedFilter (asli Pinal) dengan penambahan LazyCoders dan koreksi kesalahan ketik yang bagus DAN tambahan saya sendiri untuk menangani <STYLE>tag sebaris di dalam 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
sumber
1
Untuk informasi saya, alasan apa pun menggunakan STUFF()alih-alih REPLACE()(yang akan menjadi IMO lebih pendek)?
Patrick Honorez
Aku tidak terlalu memikirkannya. Saya hanya menyalin / memodifikasi aslinya, seperti yang ditunjukkan. Mengganti mungkin menjadi pilihan yang lebih baik. Saya ingin tahu apakah ada perbandingan kinerja antara dua fungsi yang perlu dipertimbangkan ...
Goner Doug
1
@GonerDoug bersorak untuk ini, membaca komentar yang diterima seperti, ini benar-benar perlu diperbarui.
Jono
4

Ini bukan solusi baru yang lengkap tetapi koreksi untuk solusi 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)) <> '<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
sumber
Ini berfungsi untuk saya setelah saya menggunakan nvarchar daripada varchar karena saya menggunakan karakter unicode di dalam tag html
Shadi Namrouti
3

Coba ini. Ini adalah versi modifikasi dari yang diposting oleh RedFilter ... SQL ini menghapus semua tag kecuali BR, B, dan P dengan atribut yang menyertainya:

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
kodeaf
sumber
tidak berhasil untuk saya SELECT dbo.StripHtml ('<b> somestuff </b>'); mengembalikan string yang tepat itu
ladieu
@ladieu, ini diharapkan. Periksa baris pertama dari jawaban ("SQL ini menghapus semua tag kecuali BR, B, dan P dengan atribut yang menyertainya").
Peter Herdenborg
fungsi SQL ini salah. Silakan lihat jawaban di bawah ini untuk fungsi yang dikoreksi.
futureelite7
@ futureelite7 menggunakan "di bawah" dan "di atas" sebagai referensi untuk menemukan jawaban di halaman SO adalah tidak masuk akal, karena urutan jawaban dapat diubah menggunakan tab di atas (dan lebih jauh lagi, pemungutan suara dapat mengubah urutan jawaban). Harap tentukan jawaban menggunakan nama penulis yang mempostingnya
Caius Jard
3

Bagaimana jika menggunakan XQuery dengan satu liner:

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

Ini mengulang semua elemen dan mengembalikan teks () saja.

Untuk menghindari teks di antara elemen yang digabungkan tanpa spasi, gunakan:

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))

Dan untuk menanggapi "Bagaimana Anda menggunakan ini untuk kolom:

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

Untuk kode di atas, pastikan Anda html_columnadalah tipe data xml, jika tidak, Anda perlu menyimpan html versi cast sebagaixml . Saya akan melakukan ini sebagai latihan terpisah ketika Anda memuat data HTML, karena SQL akan membuat kesalahan jika menemukan xml dalam format yang salah, misalnya tag awal / akhir tidak cocok, karakter tidak valid.

Ini sangat bagus saat Anda ingin membuat frasa pencarian, menghapus HTML, dll.

Perhatikan bahwa ini mengembalikan tipe xml, jadi CAST atau COVERT ke teks jika sesuai. Versi xml dari tipe data ini tidak berguna, karena ini bukan XML yang dibentuk dengan baik.

Arvin Amir
sumber
Tanpa solusi aktual untuk membuang dari xml, saya merasa ini adalah solusi parsial terbaik.
Dennis Jaheruddin
CAST (@xml sebagai varchar (max)). Atau CONVERT (xml), @XML). Diasumsikan sebagian besar pengembang akan mengetahuinya.
Arvin Amir
1
Sangat masuk akal untuk berasumsi bahwa pengembang tahu cara melakukan transmisi, tetapi perlu diingat bahwa seseorang yang membaca jawaban Anda mungkin tidak secara langsung melihat bahwa transmisi 'sederhana' adalah semua yang perlu dilakukan. Terutama karena disebutkan bahwa kami dapat melakukan cast jika sesuai . - Saya tidak mencoba menjadi negatif, hanya berharap ini membantu Anda dalam menciptakan jawaban yang lebih mudah dikenali sebagai berguna!
Dennis Jaheruddin
Jadi bagian mana dari ini adalah nama kolom? Katakanlah saya memiliki tabel yang disebut datadengan kolom yang disebut htmldan saya ingin memilih semua nilai di kolom itu tetapi menghapus tag html bagaimana saya bisa menggunakan jawaban Anda untuk mencapai itu?
Felix Eve
2

Ini adalah versi yang tidak memerlukan UDF dan berfungsi meskipun HTML berisi tag tanpa mencocokkan tag penutup.

TRY_CAST(REPLACE(REPLACE(REPLACE([HtmlCol], '>', '/> '), '</', '<'), '--/>', '-->') AS XML).value('.', 'NVARCHAR(MAX)')
Sejuk
sumber
1

Sementara jawaban Arvin Amir mendekati solusi satu baris penuh, Anda dapat mampir di mana saja; dia mendapat sedikit bug dalam pernyataan pilihnya (kehilangan akhir baris), dan saya ingin menangani referensi karakter yang paling umum.

Apa yang akhirnya saya lakukan adalah ini:

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]

Tanpa kode referensi karakter, dapat disederhanakan menjadi ini:

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

Kode Patrick Honorez perlu sedikit perubahan.

Ini mengembalikan hasil yang tidak lengkap untuk html yang berisi &lt;atau&gt;

Ini karena kode di bawah bagian tersebut

- Hapus apa pun di antara tag

sebenarnya akan menggantikan <> menjadi tidak ada. Cara mengatasinya adalah dengan menerapkan dua baris di bawah ini di akhir:

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
sumber