sql - 从存储为 nvarchar 的 xml 中提取数据

标签 sql sql-server xml sql-server-2008 xml-parsing

我必须提取电子邮件Subject来自XML存储为nvarchar .

我正在使用此查询:

SELECT rtrim((SELECT CAST(
                    SUBSTRING(
                        [XML]
                        ,patindex('%<SUBJECT>%', [XML])
                        ,patindex('%</SUBJECT>%', [XML])-patindex('%<SUBJECT>%', [XML])+len('</SUBJECT>')
                    ) as XML).value('(/SUBJECT/OPTION)[1]','nvarchar(2000)')
            FROM   dbo.Mails 
)) as SUBJECT

此查询的作用是首先提取包含电子邮件主题 ( <SUBJECT>....</SUBJECT> ) 的字符串,我将其转换为 XML,然后使用 value 获取主题值。 XML 的功能。

这工作正常,但在某些情况下,XML 格式不正确并且解析失败。示例:

DECLARE @XMLData XML =  '<SUBJECT>
      <OPTION CONSTRAINT="MASTER.IN_TITLE = ''  OR  MASTER.IN_LASTNAME = ''"><![CDATA[Découvrez nos offres de location]]>
      </OPTION>
      <OPTION CONSTRAINT="IN_TITLE <> '' AND MASTER.IN_LASTNAME <> ''"><![CDATA[~IN_TITLE~ ~IN_LASTNAME~, découvrez nos offres de location]]>
      </OPTION>
   </SUBJECT>'

select rtrim((@XMLData).value('(/SUBJECT/OPTION)[1]','nvarchar(2000)') )

这里是Option属性 Constraint我有一个特殊的角色< ,如果我尝试转义这个字符,它就会转义所有其他字符,并且我会丢失 XML 结构。那么如何逃脱呢?

另一个例子是这样的:

DECLARE @XMLData XML =  '<SUBJECT>
      <OPTION NAME="DEFAULT"><![CDATA[~(IF((IN_TITLE<>'' AND IN_LASTNAME<>''),IN_TITLE&' '&IN_LASTNAME&',',''))~ nos plus belles réalisations de 2015]]>
      </OPTION>
   </SUBJECT>'

select rtrim((@XMLData).value('(/SUBJECT/OPTION)[1]','nvarchar(2000)') )

这里我在 &IN_LASTNAME& 附近遇到错误但我认为我们不需要转义 CDATA 中的特殊字符!

有人有解决方案来避免解析时出现这些错误吗?

最佳答案

这些 XML 是如何生成的?这在你的控制之下吗?三个邪恶字符“<、>和&必须特殊对待,要么CDATA,要么转义。如果 XML 生成正确,那么应该不可能将它们放在禁止的地方...

这里有两个工作示例。第二个与里斯琼斯相同...... 在第一个示例中,我将“<>”替换为 <>

顺便说一句:显然,当您处理其他特殊字符时,您应该使用 N'string' 标记字符串,以将其读取为 unicode

DECLARE @XMLData XML =  REPLACE(N'<SUBJECT>
      <OPTION CONSTRAINT="MASTER.IN_TITLE = ''  OR  MASTER.IN_LASTNAME = ''"><![CDATA[Découvrez nos offres de location]]>
      </OPTION>
      <OPTION CONSTRAINT="IN_TITLE <> '' AND MASTER.IN_LASTNAME <> ''"><![CDATA[~IN_TITLE~ ~IN_LASTNAME~, découvrez nos offres de location]]>
      </OPTION>
   </SUBJECT>','<>','&lt;&gt;');

select rtrim((@XMLData).value('(/SUBJECT/OPTION)[1]','nvarchar(2000)') );
GO

DECLARE @XMLData XML =  N'<SUBJECT>
      <OPTION NAME="DEFAULT"><![CDATA[~(IF((IN_TITLE<>'''' AND IN_LASTNAME<>''''),IN_TITLE&'' ''&IN_LASTNAME&'','',''''))~ nos plus belles réalisations de 2015]]>
      </OPTION>
   </SUBJECT>'

select rtrim((@XMLData).value('(/SUBJECT/OPTION)[1]','nvarchar(2000)') )

关于sql - 从存储为 nvarchar 的 xml 中提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37862046/

相关文章:

xml - PowerShell 的 Import-Clixml 来自字符串

xml - 使用用户输入数据在 angularjs 中生成 xml 并将其发送到 Web 服务

mysql - 用于排序排行榜的 SQL 查询

java - SaxonB 9.0 与 SaxonB 9.1.0.8 和 xs :boolean vs. xs:字符串类型错误

php - MySQL连接多个表

mysql - 两个表之间的数据合并

MySQL查看多个表的count和sum等操作

sql - 使用 SQL 层次结构语法

sql - 如何将 UNION 语句转换为 JOIN 语句

SQL 在选择特定 ID 时获取序数索引