验证 HTML 输入字符串

Nis*_*ant 3 sql-server

的部分解决方案是让所有的Notes (VARCHAR)地方有一个不平衡<>。但是我怎么能写一个查询呢?

例如:

Input: <html>Hello World</html>
Output: Valid HTML

Input: <html><Hello World</html>
Output: Invalid HTML

Input: <html><Hello World></html>
Output: Valid HTML (Marking it Valid is OK for my use case)
But hey isn't that a valid HTML? It could be <name attribute>
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来检查“无效”HTML,其中“无效”被定义为 HTML 内容,<后面跟着一些HTML Element根据规范无效的字符?

最初我以为我可以检查<name后跟一个(空格),但 HTML 属性的语法为 as<name attribute>在最后关闭。

Pau*_*ite 8

如果您只想确认输入字符串由一系列<...>元素组成:

  1. <使用您最喜欢的字符串拆分器拆分字符上的字符串
  2. 第一个元素必须为空
  3. 后续元素必须只包含一个>字符

如果每个元素都通过了上面的测试,则输入字符串是有效的。

例子

字符串拆分器

我正在使用由 Solomon Rutzky 提供SQL#.String_Split4k的免费版 SQLCLR SQLsharp 库中的流式表值函数。

如果输入字符串可能长于 4000 个字符,则将使用(效率较低的)SQL#.String_Split函数代替(它处理最多 2GB 的字符串)。

任何可以使用序列号正确返回空元素的有效 字符串拆分器(T-SQL 或其他方式)都可以使用。

下面的示例显示了输出SQL#.String_Split4k返回的排序。

第一个参数是要拆分的字符串。第二个参数是分隔符。第三个参数 ( SplitOption ) 设置为 1,这意味着保留空元素。

SELECT
    SS.SplitNum,
    SS.SplitVal
FROM SQL#.String_Split4k(N'<a><b><c>', N'<', 1) AS SS;
Run Code Online (Sandbox Code Playgroud)

输出:

???????????????????????????
? 分割数 ? 分割值 ?
???????????????????????????
? 1 ? ?
? 2 ? > ?
? 3 ? 乙> ?
? 4 ? c> ?
???????????????????????????

表和测试数据

CREATE TABLE #T
(
    row_id integer IDENTITY PRIMARY KEY,
    string varchar(50) NOT NULL
);

INSERT #T 
    (string)
VALUES 
    ('<html>Hello World</html>'),
    ('<html><Hello World</html>'),
    ('<html><Hello World></html>');
Run Code Online (Sandbox Code Playgroud)

解决方案

SELECT
    T.row_id,
    string = (SELECT TOP (1) T2.string FROM #T AS T2 WHERE T2.row_id = T.row_id),
    is_valid =
        MIN
        (
            CASE
                -- First element must be blank
                WHEN SS.SplitNum = 1 AND SS.SplitVal = N'' THEN 1
                WHEN SS.SplitNum = 1 THEN 0
                -- Other elements must contain exactly one >
                WHEN SS.SplitVal NOT LIKE N'%>%' THEN 0
                WHEN SS.SplitVal LIKE N'%>%>%' THEN 0
                -- Otherwise valid
                ELSE 1
            END
        )
FROM #T AS T
CROSS APPLY SQL#.String_Split4k(T.string, '<', 1) AS SS
GROUP BY T.row_id
ORDER BY T.row_id;
Run Code Online (Sandbox Code Playgroud)

输出

SELECT
    SS.SplitNum,
    SS.SplitVal
FROM SQL#.String_Split4k(N'<a><b><c>', N'<', 1) AS SS;
Run Code Online (Sandbox Code Playgroud)