我正在使用SQL Server的CONVERT XML函数将字符串转换为XML。输入字符串有时其中包含错误的数据,我需要在SQL Server中的函数中清除它。
数据如下:
<a>test</a>test<b>test
并以此进行转换:
select CONVERT(XML,'<a>test</a>test<b>test')
在使用CONVERT时,此错误显示为“输入意外结束”。 b标记根本不是一个标记,只是有人键入了带有有效XML的标记。
我需要摆脱它的b标签或在其末尾加一个斜杠,以便它是一个自闭合标签。
SQL Server中有什么方法可以识别未关闭的标签?我能弄清楚的唯一方法是编写自己的XML解析器...不是我现在想做的事情。数据已经在SQL Server中,因此无法在用户输入上进行修改。
任何帮助将不胜感激。
ETA:咬住子弹,然后对其进行解析。下面的代码非常讲究。请注意,这不会修复所有未关闭的标签...只有那些没有关闭标签且名称相同的标签。希望真正找到未封闭标签的任何人...祝您好运!
欢迎对此代码进行任何改进!
DECLARE @OPENTAGS TABLE (
tag VARCHAR(64)
);
DECLARE @CLOSETAGS TABLE (
tag VARCHAR(64)
);
DECLARE @P INT=0;
DECLARE @Tag VARCHAR(64);
DECLARE @IsOpen INT=0;
DECLARE @IsClosingTag INT=0;
DECLARE @C nchar(1);
WHILE @P<LEN(@InputString)
BEGIN
SET @C = SUBSTRING(@InputString,@P+1,1)
IF @IsOpen=0
BEGIN
IF @C='<'
BEGIN
SET @IsOpen=1;
SET @IsClosingTag=0;
SET @Tag='';
END
END
ELSE
BEGIN
IF @C='/'
BEGIN
IF LEN(@Tag)=0
BEGIN
SET @IsClosingTag=1;
END
ELSE
BEGIN
SET @IsOpen=0;
SET @Tag='';
END
END
IF @C='>'
BEGIN
IF @IsClosingTag=0
BEGIN
INSERT INTO @OPENTAGS (tag) VALUES(@Tag)
END
ELSE
BEGIN
INSERT INTO @CLOSETAGS (tag) VALUES(@Tag)
END
SET @IsOpen=0;
SET @Tag='';
END
IF (ASCII(@C)>=65 AND ASCII(@C)<=90) OR (ASCII(@C)>=97 AND ASCII(@C)<=122)
BEGIN
SET @Tag=@Tag+@C;
END
END
SET @P = @P + 1;
END
IF (SELECT COUNT(DISTINCT tag) FROM @OPENTAGS) > (SELECT COUNT(DISTINCT tag) FROM @CLOSETAGS)
BEGIN
DECLARE @@badtag nvarchar(64);
DECLARE badtags CURSOR FOR
SELECT * FROM @OPENTAGS WHERE tag NOT IN (SELECT tag FROM @CLOSETAGS);
OPEN badtags;
FETCH NEXT FROM badtags INTO @@badtag;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @InputString = REPLACE(@InputString,'<' + @@badtag + '>', '<' + @@badtag + '/>');
FETCH NEXT FROM badtags INTO @@badtag;
END;
CLOSE badtags;
DEALLOCATE badtags;
END
答案 0 :(得分:0)
简短的回答:不,没有内置的东西。如您所知,SQL Server可以判断XML无效。它不能做的是告诉您确切的位置。最好的办法是捕获错误,将不良数据写入某些“拒绝”表,然后解析SQL外部的拒绝项,以找出问题所在。