我有一个函数可以从给定的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>
预期输出为:
“ - 这是一个字符串。”
但是当我使用我的功能时,我得到一个奇怪的结果。如果我将其复制到编辑器,输出如下所示:
“
- 这是一个字符串。”
如果我将结果直接复制到SQL Server编辑器,它会在开头获得一个额外的(更宽的)连字符:
“
- 这是一个字符串。”
如何在没有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, ' ', '')))
结果看起来一样(空格和附加连字符仍在那里)......
答案 0 :(得分:2)
当您将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
定义... < / p>
尝试使用此代码按字节读取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
...