我创建了一个问题的简化版本:
DECLARE @X XML =
'<Root xmlns="TestNS" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Test>
<Id>1</Id>
<InnerCollection>
<InnerItem>
<Value>1</Value>
</InnerItem>
<InnerItem>
<Value>2</Value>
</InnerItem>
<InnerItem>
<Value>3</Value>
</InnerItem>
</InnerCollection>
</Test>
<Test>
<Id>2</Id>
<InnerCollection>
<InnerItem>
<Value>5</Value>
</InnerItem>
<InnerItem>
<Value>6</Value>
</InnerItem>
<InnerItem>
<Value>7</Value>
</InnerItem>
</InnerCollection>
</Test>
</Root>'
我正在尝试编写一个查询
<Test>
元素,并将其分解为一行。在每一行中,我都希望选择Id和InnerCollection作为XML。我想为第一行(Id:1)创建此InnerCollection XML:
<InnerCollection xmlns="Reed.Api" xmlnsi="http//www.w3.org/2001/XMLSchema-instance">
<InnerItem>
<Value>1</Value>
</InnerItem>
<InnerItem>
<Value>2</Value>
</InnerItem>
<InnerItem>
<Value>3</Value>
</InnerItem>
</InnerCollection>
我试着用这个查询来做这件事,但它在元素上放了一个我不想要的命名空间:
;WITH XMLNAMESPACES
(
DEFAULT 'TestNS'
, 'http://www.w3.org/2001/XMLSchema-instance' AS i
)
SELECT
X.value('Id[1]', 'INT') Id
-- Creates a p1 namespace that I don't want.
, X.query('InnerCollection') InnerCollection
FROM @X.nodes('//Test') AS T(X)
我的谷歌功能今天不是很强大,但我想这并没有让这个该死的函数被称为查询变得更容易。我愿意使用查询方法以外的其他方法来创建该XML值。
我可以使用这种方法:
;WITH XMLNAMESPACES
(
DEFAULT 'TestNS'
, 'http://www.w3.org/2001/XMLSchema-instance' AS i
)
SELECT
X.value('Id[1]', 'INT') Id
,CAST(
(SELECT
InnerNodes.Node.value('Value[1]', 'INT') AS 'Value'
FROM X.nodes('./InnerCollection[1]//InnerItem') AS InnerNodes(Node)
FOR XML PATH('InnerItem'), ROOT('InnerCollection')
) AS XML) AS InnerCollection
FROM @X.nodes('//Test') AS T(X)
但这涉及到调用其上的节点,将其分解为可选择的内容,然后使用FOR XML将其重新选择为XML。。。从一开始就是XML。这似乎是一种效率低下的方法,所以我希望这里的人能有更好的想法。