我有一个函数可以从给定的 XML 字符串中删除 HTML 标签,如下所示:
ALTER FUNCTION dbo.fGetTextWithoutHtml
(
@Html XML
)
RETURNS NVARCHAR(2000)
AS
BEGIN
DECLARE @text NVARCHAR(2000) = CONVERT(NVARCHAR(2000), @html)
DECLARE @start INT
DECLARE @end INT
DECLARE @length INT
SET @start = CHARINDEX('<', @text)
SET @end = CHARINDEX('>', @text, CHARINDEX('<', @text))
SET @length = (@end - @start) + 1
WHILE @start > 0 AND @end > 0 AND @length > 0
BEGIN
SET @text = STUFF(@text, @start, @length, '')
SET @start = CHARINDEX('<', @text)
SET @end = CHARINDEX('>', @text, CHARINDEX('<', @text))
SET @length = (@end - @start) + 1
END
RETURN LTRIM(RTRIM(@text))
END
输入 XML 如下所示:
<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> <p>- This is a string.<br /></p></html>
预期输出为:
"- This is a string."
但是当我使用我的函数时,我得到了一个奇怪的结果。如果我将其复制到编辑器,输出将如下所示:
"
- This is a string."
如果我将结果直接复制到 SQL Server 编辑器,它会在开头获得一个额外的(更宽的)连字符:
"
-- This is a string."
如何获取没有 HTML 标签、附加连字符和前导空格的字符串?
编辑
我试图找出输入字符串中是否有不可打印的字符:
PRINT CONVERT(NVARCHAR(2000), @html)
结果如下:
<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve">  <p>- This is a string.<br /></p></html>
有 
在我的绳子里。但当我改变了
RETURN LTRIM(RTRIM(@text))
至
RETURN LTRIM(RTRIM(REPLACE(@text, ' ', '')))
结果看起来是一样的(空格和额外的连字符仍然存在)...
最佳答案
当您将 HTML 作为 XML 传递并且有一个“xhtml”命名空间时,我建议使用 XML 方法读取您的内容:
DECLARE @x XML = N'<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> <p>- This is a string.<br /></p></html>';
WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/1999/xhtml')
SELECT Each.node.value('(text())[1]','nvarchar(max)') AS pContent
FROM @x.nodes('/html//*') Each(node)
结果看起来是正确的,但是连字符之前有一个无法打印的符号(您可以通过将光标移到此文本上来看到这一点。有一个位置,您的光标不会移动...现在尝试相同的代码< em>没有前导“N”。现在连字符之前会出现一个问号。这是一个 unicode 符号,未为 VARCHAR
定义。 ..
尝试使用此代码按字节读取您的 unicode 字符串:
CREATE FUNCTION dbo.SingleBytes(@SomeText NVARCHAR(MAX))
RETURNS TABLE
AS
RETURN
WITH nr10 AS
(
SELECT * FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tbl(A)
)
,RunningNumbers AS
(
SELECT TOP (ISNULL(DATALENGTH(@SomeText),0)) ROW_NUMBER() OVER(ORDER BY (SELECT(NULL))) AS Nmbr FROM nr10,nr10 AS a,nr10 AS b,nr10 AS c,nr10 AS d,nr10 AS e,nr10 AS f,nr10 AS g
)
,ByteWise AS
(
SELECT CAST(CAST(@SomeText AS VARBINARY(MAX)) AS VARCHAR(MAX)) AS ByteWiseText
)
SELECT SUBSTRING(ByteWiseText,Nmbr,1) AS TheCharacter
,ASCII(SUBSTRING(ByteWiseText,Nmbr,1)) AS ASCII_Code
FROM ByteWise,RunningNumbers;
GO
SELECT * FROM dbo.SingleBytes(N'<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> <p>- This is a string.<br /></p></html>');
GO
DROP FUNCTION dbo.SingleBytes;
你发现,在>
和-
之间有11-32,即0B20, find details here
这可能是列表的前导标志?
无论如何:您可以这样定义:
DECLARE @EvilChar NVARCHAR(1)=CAST(CAST(CHAR(11) + CHAR(32) AS VARBINARY(2)) AS NVARCHAR(1));
您可以在REPLACE
中使用此变量...
祝你好运:-)
关于xml - 从字符串中删除 HTML 标签未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37789323/