首页 > 解决方案 > SQL - 从非标准 XML 格式解析 XML

问题描述

我们有一个第三方应用程序,它生成一个 XML 文件,其中包含从移动设备提交的数据;这将返回到 SQL 数据库表并位于 XML 类型字段中。

我需要提取我似乎已经想出到一定程度的具体答案,但我想知道我是否可以使用“节点”或某种形式的外部应用/交叉应用连接来完成这项工作,然后直接查询而不是比每个值的整行。

以下示例:

CREATE TABLE [dbo].[zz_PhoneData_Test](
    [RecID] [bigint] NOT NULL,
    [TasksetID] [bigint] NULL,
    [FormData] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT [reports].[zz_PhoneData_Test] ([RecID],[TasksetID], [FormData]) VALUES (35512921264, 593, N'<fd u="=afa01113c0674a3fbdc8354c7aa538ab" b="0" v="1"><field i="1">12345</field><field i="2">E-mail Test</field><field i="3">1</field></fd>')





WITH [cte_test] AS
(
    SELECT TOP(10)
           [pd].[RecId],
           REPLACE(REPLACE(CAST(FormData.query('/fd/field[@i=1]') AS NVARCHAR(100)),'<field i="1">',''),'</field>','') AS [Order]
    FROM reports.[zz_PhoneData_Test] [pd]
)

SELECT  [cte].[RecId],
        [cte].[Order],
        CASE WHEN PATINDEX('[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][-][0-9][0-9][0-9][0-9]', [Order] ) = 1 THEN 'Valid'
             WHEN PATINDEX('[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]', [Order] ) = 1 THEN 'Valid'
             WHEN PATINDEX('[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]', [Order] ) = 1 THEN 'Valid'
             ELSE 'Invalid' END AS [Validation]
FROM [cte_test] [cte]
GO

有了上面的内容,应该足以让您了解我在做什么,忽略 PATINDEX,因为它可以被排除在测试之外,我希望能够提取“XML”中 3 个答案中每一个的值" 不使用 'query' 选项,而是通过 'nodes' 方法,虽然我不确定如何执行此操作?任何帮助或指导表示赞赏。

标签: sqlsql-serverxmltsqlxml-parsing

解决方案


您可以使用如下nodes方法:

SELECT t.RecID
     , t.TasksetID
     , n.field.value('@i', 'INT') AS attr
     , n.field.value('.', 'NVARCHAR(100)') AS text
FROM PhoneData AS t
CROSS APPLY t.FormData.nodes('/fd/field') AS n(field)

推荐阅读