使用命名空间选择列作为XML

时间:2014-04-25 15:07:56

标签: sql xml tsql sql-server-2008-r2

我需要从表中选择一些列作为XML,其中包含名称空间以及其他列。例如,我有以下表格布局:

ID  C1  X1C1  X1C2  X2C3
1   A   1     2     3

查询应返回的内容是:

ID  C1  XmlData
1   A   <xmldata1>
2   A   <xmldata2>

<xmldata1>的位置:

<Root xmlns:xsd="w3.org/2001/XMLSchema" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:mst="microsoft.com/wsdl/types/">
  <Child attrib="C1">
    <ChildValue xsi:type="xsd:integer">1</ChildNode>
  </Child>
  <Child attrib="C2">
    <ChildNode xsi:type="xsd:integer">2</ChildNode>
  </Child>
</Root>

<xmldata2>将是:

<Rootxmlns:xsd="w3.org/2001/XMLSchema" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:mst="microsoft.com/wsdl/types/">
  <Child attrib="C3">
    <ChildNode xsi:type="xsd:integer">3</ChildNode>
  </Child>
</Root>

我有一个很好的参考如何从this SO question构建xml,但我无法放入名称空间。如果可能的话怎么做?

编辑: 我尝试使用以下查询来获取所需的结果:     选择1个ID,&#39; A&#39; C1,1 X1C1,2 X1C2,3 X2C3     到#t

;with xmlnamespaces('w3.org/2001/XMLSchema' as xsd, 'w3.org/2001/XMLSchema-instance' as xsi, 'microsoft.com/wsdl/types/' as mst)
select ID, C1, (select (SELECT 'C1' "@attrib", 'xsd:integer' "ChildValue/@xsi:type",t.X1C1 as 'ChildValue' FOR XML PATH('Child'), type),(SELECT 'C2' "@name", 'xsd:integer' "ChildValue/@xsi:type", t.X1C2 as 'ChildValue' FOR XML PATH('Child'), type) FOR XML PATH('Root'), type) as property_data 
FROM #t t

drop table #t

以下是其xml部分的输出:

<Root xmlns:mst="microsoft.com/wsdl/types/" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:xsd="w3.org/2001/XMLSchema">
<Child xmlns:mst="microsoft.com/wsdl/types/" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:xsd="w3.org/2001/XMLSchema" attrib="C1">
    <ChildValue xsi:type="xsd:integer">1</ChildValue>
  </Child>
  <Child xmlns:mst="microsoft.com/wsdl/types/" xmlns:xsi="w3.org/2001/XMLSchema-instance" xmlns:xsd="w3.org/2001/XMLSchema" name="C2">
    <ChildValue xsi:type="xsd:integer">2</ChildValue>
  </Child>
</Root>

我无法摆脱Child节点中的命名空间。

3 个答案:

答案 0 :(得分:5)

我使用了这个解决方案:TSQL for xml add schema attribute to root node

基本上,我没有把命名空间放在开头,但是在生成所需的xml结构之后,我将xml转换为nvarchar(max)并用所需的命名空间替换了根节点。

我还需要在属性中使用名称空间前缀。为此,我使用了一个伪属性名称,我将其替换为正确的xml名称空间前缀。

这两个操作都是使用tsql REPLACE函数完成的。 Hacky但找不到其他正确的方法。

答案 1 :(得分:1)

您需要包含WITH xmlnamespaces,例如:

;with xmlnamespaces('w3.org/2001/XMLSchema' as xsd, 'w3.org/2001/XMLSchema-instance' as xsi, 'microsoft.com/wsdl/types/' as mst)
select ID, C1,
(select 
(SELECT 'C1' "@name",t.C1 as 'value'FOR XML PATH('Property'), type),
(SELECT 'C2' "@name",t.C2 as 'value'FOR XML PATH('property'), type)
FOR XML PATH('data'), type) as property_data 
FROM TableName t

答案 2 :(得分:1)

你尝试过吗? 从tableName

中选择XML_COL_NAME.value('(/ rootNode // childNode / node())[1]','nvarchar(64)')