Xml 从字符串中删除HTML标记未按预期工作

Xml 从字符串中删除HTML标记未按预期工作,xml,string,tsql,xhtml,special-characters,Xml,String,Tsql,Xhtml,Special Characters,我有一个函数,可以从给定的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 @len

我有一个函数,可以从给定的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
<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> &#x20;<p>​- This is a string.<br /></p></html>
DECLARE @EvilChar NVARCHAR(1)=CAST(CAST(CHAR(11) + CHAR(32) AS VARBINARY(2)) AS NVARCHAR(1));
结果如下:

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
<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> &#x20;<p>​- This is a string.<br /></p></html>
DECLARE @EvilChar NVARCHAR(1)=CAST(CAST(CHAR(11) + CHAR(32) AS VARBINARY(2)) AS NVARCHAR(1));


结果看起来是一样的(空格和附加的连字符仍然存在).

当您以XML形式传入HTML时,有一个“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)
您会发现,在
-
之间有11-32,这是

这可能是列表的主要标志

无论如何:您可以这样定义:

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
<html xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve"> &#x20;<p>​- This is a string.<br /></p></html>
DECLARE @EvilChar NVARCHAR(1)=CAST(CAST(CHAR(11) + CHAR(32) AS VARBINARY(2)) AS NVARCHAR(1));
您可以在
替换中使用此变量


祝您好运:-)

这与函数中的代码无关,而是与输入有关(以及与XML的转换方式)。您描述的问题可以通过以下方法复制:
declare@xxml='​- 这是一个字符串。

'print convert(NVARCHAR(2000),@x)
看起来在
-
谢谢@KeithHall的
之间有一个隐藏的/不可打印的字符。我发现有一个不可打印的字符。但我找不到如何移除它。看我编辑的问题。@KeithHall猜对了!你的假设是正确的。有一个前导的
0x0B20
,可能是一个虚线列表符号。。。