我的目标是打破这个xml,这样我就可以为每个Record Row获取Field元素并插入到SQL表中。 我根本无法弄清楚如何遍历网格层次结构。我已经能够运行一些xquery 对它的命令,但只在最高级别,如下所示。请帮助完全放下 为每一行的每个字段执行字段元素值。
declare @Responsetext varchar(8000)
set @Responsetext =
'<GridResponse xmlns="http://abcd.abcd.net/aapi/2009/08/">
<Brand id="1111">API Starter App</Brand>
<User>AAA_API</User>
<Grids>
<Grid type="subscriber">
<Record row="1">
<Fields>
<Field element="subscriber_id">111107293</Field>
<Field element="bounce_date" />
<Field element="cancellation_mailing_instance_id" />
<Field element="cancellation_message" />
<Field element="cancellation_date" />
<Field element="email">aaaa4@gmail.com</Field>
<Field element="is_repeated_bouncer">0</Field>
<Field element="is_unsubscriber">0</Field>
<Field element="modified_date">2015-04-07T13:19:09.3400000Z</Field>
<Field element="service_since_date">2011-10-17T13:23:38.7800000Z</Field>
<Field element="user_id" />
</Fields>
</Record>
<Record row="2">
<Fields>
<Field element="subscriber_id">111169135</Field>
<Field element="bounce_date" />
<Field element="cancellation_mailing_instance_id" />
<Field element="cancellation_message" />
<Field element="cancellation_date" />
<Field element="email">aaaa.bass@aaa.org</Field>
<Field element="is_repeated_bouncer">0</Field>
<Field element="is_unsubscriber">0</Field>
<Field element="modified_date">2014-12-15T17:30:18.2230000Z</Field>
<Field element="service_since_date">2011-10-19T14:11:26.6370000Z</Field>
<Field element="user_id" />
</Fields>
</Record>
</Grid>
</Grids>
</GridResponse>
'
这段代码给了我节点树,但是我无法弄清楚如何调整它以隔离8级深度的字段值。
--This CTE gives you the Node Tree
WITH Xml_CTE AS
(
SELECT
CAST('/' + node.value('fn:local-name(.)',
'varchar(100)') AS varchar(100)) AS name,
node.query('*') AS children
FROM @XmlResponse.nodes('/*') AS roots(node)
UNION ALL
SELECT
CAST(x.name + '/' +
node.value('fn:local-name(.)', 'varchar(100)') AS varchar(100)),
node.query('*') AS children
FROM Xml_CTE x
CROSS APPLY x.children.nodes('*') AS child(node)
)
SELECT distinct name
FROM Xml_CTE x
OPTION (MAXRECURSION 1000)
如果我将xml推入表而不是使用变量,我可以像这样得到根节点,但仍然无法达到字段级别。
--Parent Node -- Returns GridResponse
SELECT
(
SELECT
c.value('local-name(.)', 'nvarchar(50)')
FROM
xmldata.nodes('/*') AS r(c)
) AS RootParent
FROM [dbo].subscriber_xml
我可以查询节点是否存在,并获取root和Brand子节点,但不能获取Grids子节点。这是非常令人困惑的,为什么一个工作,另一个不工作。
SELECT XmlData.exist('(/*[1][contains(local-name(.),"GridResponse")])')
FROM [dbo].subscriber_xml
SELECT XmlData.exist('(/*/*[1][contains(local-name(.),"Brand")])')
FROM [dbo].subscriber_xml
SELECT XmlData.exist('(/*/*[1][contains(local-name(.),"Grids")])')
FROM [dbo].subscriber_xml
答案 0 :(得分:0)
这是我的建议(请将@Responsetext
的声明更改为XML
):
WITH XMLNAMESPACES(DEFAULT 'http://abcd.abcd.net/aapi/2009/08/')
SELECT OneRecord.value('@row','varchar(max)') AS RowID
,OneRecord.value('(Fields/Field[@element="subscriber_id"])[1]','varchar(max)') AS subscriber_id
,OneRecord.value('(Fields/Field[@element="bounce_date"])[1]','varchar(max)') AS bounce_date
,OneRecord.value('(Fields/Field[@element="cancellation_mailing_instance_id"])[1]','varchar(max)') AS cancellation_mailing_instance_id
,OneRecord.value('(Fields/Field[@element="cancellation_message"])[1]','varchar(max)') AS cancellation_message
,OneRecord.value('(Fields/Field[@element="cancellation_date"])[1]','varchar(max)') AS cancellation_date
,OneRecord.value('(Fields/Field[@element="email"])[1]','varchar(max)') AS email
,OneRecord.value('(Fields/Field[@element="is_repeated_bouncer"])[1]','varchar(max)') AS is_repeated_bouncer
,OneRecord.value('(Fields/Field[@element="is_unsubscriber"])[1]','varchar(max)') AS is_unsubscriber
,OneRecord.value('(Fields/Field[@element="modified_date"])[1]','varchar(max)') AS modified_date
,OneRecord.value('(Fields/Field[@element="service_since_date"])[1]','varchar(max)') AS service_since_date
,OneRecord.value('(Fields/Field[@element="user_id"])[1]','varchar(max)') AS user_id
--INTO tempTable
FROM @Responsetext.nodes('/GridResponse/Grids/Grid/Record') AS Records(OneRecord)
这将在表格中显示您的数据。
只需在--
之前删除INTO tempTable
,然后在其中设置您喜欢的表名。这将创建一个具有给定结构的表,并用数据填充它。
还有一点:您应该根据您的数据选择数据类型。我全部用了varchar(max)
,但您可能希望将其更改为int
,datetime
或其他任何内容......