Cách tốt nhất để tách các thẻ html khỏi một chuỗi trong máy chủ sql?


112

Tôi có dữ liệu trong SQL Server 2005 chứa các thẻ html và tôi muốn loại bỏ tất cả những thứ đó, chỉ để lại văn bản giữa các thẻ. Tốt nhất cũng nên thay thế những thứ như &lt;bằng <, v.v.

Có cách nào dễ dàng để làm điều này không hoặc ai đó đã có một số mã t-sql mẫu?

Tôi không có khả năng thêm các procs được lưu trữ mở rộng và những thứ tương tự, vì vậy tôi thích cách tiếp cận t-sql thuần túy (tốt nhất là một phương pháp tương thích ngược với sql 2000).

Tôi chỉ muốn truy xuất dữ liệu bằng html đã loại bỏ, không cập nhật nó, vì vậy lý tưởng nhất là nó sẽ được viết dưới dạng một hàm do người dùng định nghĩa, để dễ dàng sử dụng lại.

Vì vậy, ví dụ chuyển đổi điều này:

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

đến điều này:

Some useful text > more text

Câu trả lời:


161

Có một UDF sẽ làm điều đó được mô tả ở đây:

Chức năng do người dùng xác định để tách 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

Chỉnh sửa: lưu ý rằng điều này là dành cho SQL Server 2005, nhưng nếu bạn thay đổi từ khóa MAX thành một cái gì đó như 4000, nó cũng sẽ hoạt động trong SQL Server 2000.


9
Cảm ơn rất nhiều. Nhận xét ở đó liên kết đến một phiên bản cải tiến: lazycoders.blogspot.com/2007/06/… . Phiên bản này xử lý nhiều thực thể html hơn.
Rory

4
Lưu ý rằng với tư cách là một UDF chuyên sâu về chuỗi trong SQL Server 2005 trở lên, đây là một ứng cử viên hoàn hảo cho việc triển khai chức năng CLR UDF nhằm tăng hiệu suất lớn. Thông tin thêm về cách làm như vậy tại đây: stackoverflow.com/questions/34509/…
RedFilter

10
Lưu ý rằng bài đăng của lazycoders có hai lỗi chính tả. Loại bỏ các dấu ngoặc kép xung quanh CHAR(13) + CHAR(10)trong hai trong số các phần có chúng. Đủ tinh tế, tôi đã không nắm bắt được nó cho đến khi nó vượt quá độ dài của một trường ngắn (thú vị và bắt buộc đối với tôi, tất cả các thay thế đều ngắn hơn chuỗi ban đầu).
goodeye

1
Điều gì về các giá trị được mã hóa html? sẽ cần chúng được giải mã. Cảm ơn.
JDPeckham

2
Tôi đã sử dụng lazycoders, cộng với sửa lỗi chính tả từ @goodeye ở trên - hoạt động tuyệt vời. Để tiết kiệm thời gian, phiên bản blog của lazycoders ở đây: lazycoders.blogspot.com/2007/06/…
qxotk

17

Bắt nguồn từ câu trả lời @Goner Doug, với một số điều được cập nhật:
- sử dụng REPLACE nếu có thể
- chuyển đổi các thực thể được xác định trước như &eacute;(Tôi đã chọn những thực thể tôi cần :-)
- một số chuyển đổi thẻ danh sách<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

4
Tôi đã sử dụng cái này và thích nó, nhưng tôi đã thêm một cái khác thay thế vào nhóm trên cùng: </p> Tôi cũng đã đổi thành char 13 + char 10 vì thẻ cuối đoạn thường chỉ ra một dòng mới. Nó hoạt động hoàn hảo trong kịch bản cụ thể của tôi
DR

1
Phần lớn câu trả lời này hoạt động hiệu quả, nhưng có một giả định rằng tất cả các thẻ HTML của bạn đều hợp lệ. Trong trường hợp của tôi, đã xảy ra sự cố cắt bớt khi tải lên VARCHAR đã loại bỏ một số thẻ đóng. Một PATINDEX RTrim đơn giản đã thực hiện thủ thuật để loại bỏ mọi thứ khác.
matt123788

2
Ngoài thay đổi mà @DR đã thực hiện (cộng với một số thay đổi khác cần ký tự xuống dòng), tôi cũng đã di chuyển thay thế mà kết quả đó đến <>cuối cùng. Nếu không, họ đã bị xóa với các thẻ.
a_hardin

8

Nếu HTML của bạn được định dạng tốt, tôi nghĩ đây là giải pháp tốt hơn:

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

1
Điều này đã làm việc cho tôi. +1. Nhưng bạn có thể vui lòng giải thích mã của mình để các nhà phát triển hiểu nó dễ dàng hơn không? :)
Saeed Neamati

có vẻ như nó tải html dưới dạng tài liệu xml, sau đó chọn tất cả các giá trị từ nó. Lưu ý: mã này xuất hiện trên & nbsp;
JDPeckham

2
Đặt một cuộc tấn công để không đánh bom mã HTML. Rõ ràng chỉ là một cuộc tấn công nhanh chóng để sử dụng trong nhà hoặc bất cứ điều gì (giống như với UDF được chấp nhận).
dudeNumber 4

Nó phải được hình thành tốt, vì vậy nó không có khả năng chịu lỗi như RedFilter.
Micah B.

1
HTML không phải là một tập hợp con của XML. XHTML là vậy, nhưng HTML không còn đi theo con đường đó nữa.
David

7

Đây là phiên bản cập nhật của hàm này kết hợp câu trả lời RedFilter (bản gốc của Pinal) với phần bổ sung LazyCoders và sửa lỗi chính tả tốt VÀ phần bổ sung của riêng tôi để xử lý <STYLE>các thẻ nội dòng bên trong 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

1
Đối với thông tin của tôi, bất kỳ lý do nào sử dụng STUFF()thay vì REPLACE()(IMO nào sẽ ngắn hơn)?
Patrick Honorez

Tôi đã không thực sự nghĩ về nó. Tôi chỉ cần sao chép / sửa đổi bản gốc, như đã chỉ ra. Thay thế rất có thể là một lựa chọn tốt hơn. Tôi tự hỏi liệu có sự so sánh hiệu suất giữa hai chức năng để xem xét ...
Goner Doug

1
@GonerDoug cổ vũ cho điều này, đã đọc qua các nhận xét được chấp nhận như, điều này thực sự cần được cập nhật.
Jono

4

Đây không phải là một giải pháp hoàn toàn mới mà là một sự điều chỉnh cho giải pháp của 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  

Điều này làm việc cho tôi sau khi tôi sử dụng nvarchar thay vì varchar vì tôi sử dụng các ký tự unicode bên html tags
Shadi Namrouti

3

Thử cái này. Đó là phiên bản sửa đổi của phiên bản được đăng bởi RedFilter ... SQL này xóa tất cả các thẻ ngoại trừ BR, B và P với bất kỳ thuộc tính nào đi kèm:

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

không hoạt động đối với tôi SELECT dbo.StripHtml ('<b> somestuff </b>'); trả về chuỗi chính xác đó
ladieu

@ladieu, điều này được mong đợi. Kiểm tra dòng đầu tiên của câu trả lời ("SQL này loại bỏ tất cả các thẻ ngoại trừ BR, B và P với bất kỳ thuộc tính đi kèm nào").
Peter Herdenborg

hàm SQL này không chính xác. Vui lòng tham khảo câu trả lời bên dưới để biết chức năng đã sửa.
futureelite

@ futureelite7 sử dụng "bên dưới" và "bên trên" làm tham chiếu cho nơi tìm câu trả lời trên trang SO là vô nghĩa, vì thứ tự câu trả lời có thể được thay đổi bằng cách sử dụng các tab ở trên cùng (và hơn thế nữa, biểu quyết có thể thay đổi thứ tự câu trả lời). Vui lòng chỉ định câu trả lời bằng cách sử dụng tên tác giả đăng nó
Caius Jard

3

Làm thế nào về việc sử dụng XQuery với một lớp lót:

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

Điều này lặp qua tất cả các phần tử và chỉ trả về văn bản ().

Để tránh văn bản giữa các phần tử nối với nhau mà không có dấu cách, hãy sử dụng:

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

Và để trả lời "Bạn sử dụng cái này như thế nào cho một cột:

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

Đối với đoạn mã trên, hãy đảm bảo rằng bạn html_columnthuộc loại dữ liệu xml, nếu không, bạn cần lưu một phiên bản html được đúc thành xml. Tôi sẽ thực hiện việc này như một bài tập riêng khi bạn đang tải dữ liệu HTML, vì SQL sẽ gặp lỗi nếu tìm thấy xml không đúng định dạng, ví dụ: thẻ bắt đầu / kết thúc không khớp, ký tự không hợp lệ.

Đây là những thứ tuyệt vời khi bạn muốn xây dựng các cụm từ seachh, dải HTML, v.v.

Chỉ cần lưu ý rằng điều này trả về loại xml, vì vậy CAST hoặc COVERT để văn bản khi thích hợp. Phiên bản xml của kiểu dữ liệu này là vô dụng, vì nó không phải là một XML được định dạng tốt.


Nếu không có giải pháp thực tế để truyền từ xml, tôi cảm thấy như đây tốt nhất là một giải pháp từng phần.
Dennis Jaheruddin

CAST (@xml dưới dạng varchar (max)). Hoặc CHUYỂN ĐỔI (xml), @XML). Giả sử hầu hết các nhà phát triển sẽ tìm ra điều đó.
Arvin Amir

1
Chắc chắn là hợp lý khi cho rằng các nhà phát triển biết cách truyền, nhưng hãy nhớ rằng ai đó đọc câu trả lời của bạn có thể không trực tiếp thấy rằng truyền 'đơn giản' là tất cả những gì cần phải thực hiện. Đặc biệt là vì nó được đề cập rằng chúng tôi có thể cast ở những nơi thích hợp . - Tôi không cố gắng phủ định, chỉ hy vọng điều này sẽ giúp bạn trong việc tạo ra các câu trả lời dễ nhận ra là hữu ích hơn!
Dennis Jaheruddin

Vì vậy, những gì phần này là tên cột? Giả sử tôi có một bảng được gọi datavới một cột được gọi htmlvà tôi muốn chọn tất cả các giá trị trong cột đó nhưng tách các thẻ html làm cách nào tôi có thể sử dụng câu trả lời của bạn để đạt được điều đó?
Felix Eve

2

Đây là phiên bản không yêu cầu UDF và hoạt động ngay cả khi HTML chứa các thẻ không có thẻ đóng phù hợp.

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

1

Trong khi câu trả lời của Arvin Amir gần với một giải pháp một dòng đầy đủ mà bạn có thể ghé thăm ở bất cứ đâu; anh ấy có một lỗi nhỏ trong câu lệnh lựa chọn của mình (thiếu phần cuối của dòng) và tôi muốn xử lý các tham chiếu ký tự phổ biến nhất.

Cuối cùng những gì tôi đã làm là:

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]

Nếu không có mã tham chiếu ký tự, nó có thể được đơn giản hóa thành:

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

0

Mã Patrick Honorez cần một chút thay đổi.

Nó trả về kết quả không đầy đủ cho html có chứa &lt;hoặc&gt;

Điều này là do mã bên dưới phần

- Xóa bất kỳ thứ gì giữa các thẻ

trên thực tế sẽ thay thế dấu <> thành không. Cách khắc phục là áp dụng hai dòng dưới đây ở cuối:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.