xml - 从字符串中删除 HTML 标签未按预期工作

标签 xml string t-sql 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 @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"> &#x20;<p>​- This is a string.<br /></p></html>

&#x20在我的绳子里。但当我改变了

RETURN LTRIM(RTRIM(@text))

RETURN LTRIM(RTRIM(REPLACE(@text, '&#x20;', '')))

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

最佳答案

当您将 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/

相关文章:

sql - 为什么在SQL Server 中使用XML 类型来存储XML 数据?

xml - Odoo10如何在Qweb Report中显示图片?

c# - 将 datetime 解析为具有英语文化的月日时,仍将其解析为土耳其语

html - Powershell 删除字符串内容中的 HTML 标签

sql-server - 使用 Select 语句和聚合函数从另一个表更新表

java - xml 文件中的特殊字符在 JSP 上显示问号? java网络

Java 字符串输出

sql-server - 对于至少在台式电脑、笔记本电脑或打印机之一上拥有型号的每个制造商,确定其产品的最高价格。输出: maker;

sql-server - 转置并用标志识别单元格

xml - 用于 Perl 的 XSLT2.0 处理器?