带命名空间的T-Sql xml查询

时间:2012-01-18 12:18:28

标签: xml tsql

这是

的后续问题

T-Sql xml query

如果我向xml数据添加命名空间,则不会再返回任何内容。

DECLARE @xVar XML
SET @xVar = 
  '<ReportData ObjectId="123" xmlns="http://ait.com/reportdata">
  <ReportId>AAAA-BBBB-CCCCC-DDDDD</ReportId>
  <DocId>100</DocId>
  <ReportName>Drag Scraper Troubleshooting</ReportName>
  <DocType>Name</DocType>
  <StatusId>1</StatusId>
  <AuthorId>1</AuthorId>
   </ReportData>'

SELECT [ReportId]= reportdata.item.value('.', 'varchar(40)') 
FROM   @xVar.nodes('/ReportData/ReportId[1]') AS reportdata(item) 

以上查询不返回任何内容。其次,如何在单个选择中选择所有元素并返回包含所有元素作为字段的行?

我想返回一条构造如下的记录:

ReportId              | DocId | ReportName | 
AAAA-BBBB-CCCCC-DDDDD | 100   | AAAA-BBBB-CCCCC-DDDDD |

3 个答案:

答案 0 :(得分:9)

查看WITH XMLNAMESPACES

;WITH XMLNAMESPACES(DEFAULT 'http://ait.com/reportdata')
SELECT [ReportId]= reportdata.item.value('.', 'varchar(40)') 
FROM   @xVar.nodes('/ReportData/ReportId[1]') AS reportdata(item) 

答案 1 :(得分:1)

如果我的假设是正确的,并且您想要在XML文档中列出所有ReportData元素并希望将其子元素作为不同的列,那么您可以看一下这样的事情:

;WITH XMLNAMESPACES(DEFAULT 'http://ait.com/reportdata')
SELECT 
    [ReportId] = reportdata.item.value('(./ReportId)[1]', 'varchar(40)') 
  , [DocId] = reportdata.item.value('(./DocId)[1]', 'varchar(40)') 
  , [ReportName] = reportdata.item.value('(./ReportName)[1]', 'varchar(40)') 
  , [DocType] = reportdata.item.value('(./DocType)[1]', 'varchar(40)') 
  , [StatusId] = reportdata.item.value('(./StatusId)[1]', 'varchar(40)') 
  , [AuthorId] = reportdata.item.value('(./AuthorId)[1]', 'varchar(40)') 
FROM @xVar.nodes('//ReportData') AS reportdata(item)

我需要稍微查看清理命名空间声明,但它似乎对我有用......

编辑:使用Martin推荐的WITH XMLNAMESPACES子句修改了我的答案。 :)

答案 2 :(得分:1)

如果您尝试提取数据,并且记录之间的名称空间可能有所不同,则可以对名称空间前缀使用通配符。只需在OP原始代码的最后一行中的每个元素名称之前添加“ *:”,就像这样:

FROM   @xVar.nodes('/*:ReportData/*:ReportId[1]') AS reportdata(item) 

请注意,您需要在每个级别使用通配符,而不仅仅是在xml中看到名称空间声明的级别上使用通配符。这是因为名称空间是由每个级别从其之上的级别继承的。