MS SQL 2005“For XML Path”节点布局问题

时间:2009-03-26 20:26:43

标签: sql sql-server xml tsql sqlxml

我有以下查询

Select field1 as 'node1/field1',
       field2 as 'node1/field2',
  (Select field3 as 'child1/field3',
          field4 as 'child1/field4'
   From table2
   FOR XML PATH(''),TYPE,Elements)
From Table1 FOR XML PATH('Root'),Elements

这会产生:

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
  </node1>
   <child1>
     <field3>data3</field3>
     <field4>data4</field4>
   </child1>
   <child1>
     ...   
</Root>

我希望child1节点成为node1的一部分,而不是下面的单独节点。

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
    <child1>
       <field3>data3</field3>
       <field4>data4</field4>
    </child1>
    <child1>
      ...
 </node1>
 <node1>
   ...
</Root>

我尝试将node1放在子查询PATH

FOR XML PATH('node1'),TYPE,Elements)

或使用node1

为子查询字段名添加前缀
Select field3 as 'node1/child1/field3',

但两者都为子查询创建了一个新的node1元素。

有谁知道我怎么能做到这一点?

由于

4 个答案:

答案 0 :(得分:0)

你必须告诉SQL Server table1和table2是如何相关的。根据你在下面的回答,我认为这样的事情可能会起到作用:

select 
    table1.field1 as 'Node1/Field1'
,   table2.field1 as 'Node1/Child1/Field1'
,   table1.field2 as 'Node2/Field2'
from table1
left join table2 on table1.id = table2.table1id
for xml PATH(''), ROOT('Root')

这应该产生如下的XML:

<Root>
    <Node1>
        <Field1>Value</Field1>
        <Child1>
            <Field1>Value</Field1>
        </Child1>
    </Node1>
    <Node2>
        <Field2>Value</Field2>
    </Node2>
</Root>

答案 1 :(得分:0)

我没有对T-SQL和FOR XML做过很多工作,但是我通过在每个子查询之后调用FOR XML部分来解决类似的问题,如下所示,并使用PATH标识符设置节点:

SELECT field1 as "Field1",
    field2  as "Field2",
    (select
        field3 as "Field3",
        field4 as "Field4"

        from table2 t2 inner join 
        tlink tl on tl.id = t2.id inner join
        table2 on t2.id = tl.id
        group by field3, field4
        FOR XML PATH ('Child'), type
        ) 

from table2 t2 
group by field1, field2
FOR XML PATH('Node'), ROOT('Root')

返回:

<Root>
  <Node1>
    <Field1>data1</Field1>
    <Field2>data2</Field2>
    <Child1>
      <Field3>data3</Field3>
      <Field4>data4</Field4>
    </Child1>
  </Node1>
  <Node2>
    <Field1>data1.2</Field1>
    <Field2>data2.2</Field2>
    <Child2>
      <Field3>data3.2</Field3>
      <Field4>data4.2</Field4>
    </Child2>

...
  </Node2>

...
</Root>

正如Andomar所说,您需要确保正确连接数据。

我还有Group By子句,以确保数据不会“误入歧途”。我对子查询数据有问题,因为外部查询中的每个条目都复制了一个子节点(每个节点下有多个子节点与有多少节点相关。)我确定有一个简单的解释,但我是当我这样做并且从未回去检查时,工作时间紧迫...

如果这是不正确的使用或任何人都可以阐明重复组,请指出它,我会编辑...

答案 2 :(得分:0)

我的第一个示例查询并不完全正确,正如您所指出的那样。这是一个更精确的示例查询。

Select field1 as 'node1/field1',       
       field2 as 'node1/field2',  
  (Select field3 as 'child1/field3',          
        field4 as 'child1/field4'   
   From table2   
   Where table1.ID = table2.ID
   FOR XML PATH(''),TYPE,Elements),
       field5 as 'node2/field5',
       field6 as 'node2/field6'
From table1 FOR XML PATH('Root'),Elements

产生:

<Root>
  <node1>
    <field1>data1</field1>
    <field2>data2</field2>
  </node1>   
  <child1>     
    <field3>data3</field3>
    <field4>data4</field4>
  </child1>
  <node2>
    <field5>data5</field5>
    <field6>data6</field6>
  </node2>
</Root>

field5和field6是外部查询的字段,但位于不同的节点路径node2中。这就是为什么我不能在外部查询上使用PATH('node')。外部查询字段用于Root下的许多不同节点路径。我需要子节点在node1下重新运行,还有其他子查询需要在node2,node3 ...下返回 我当然希望我有意义。 这是我的第一篇文章,我将确保并在下次发布更好的样本查询。

感谢您的回答。

德克

答案 3 :(得分:0)

如果您发布一些示例数据而不是使用node1,field1,child1等可能更有意义,并解释数据来自哪些表。

XML本质上是分层的。您不能随意启动与根目录下的其他节点无关的新节点,这听起来就像您尝试的那样。

<node1> ..到.. </node1>内的所有内容都与一条记录及其子查询生成的数据有关。下一个节点序列将结构复制为<node2> ..到.. </node2>以便下一条记录。

如果您想在每个节点下进行更多子查询,那么只需在SQL中使用自己的FOR XML PATH('SubNodeName')

编写每个子查询

发布您的XSD或XML代码示例,我会看看我是否可以解决您想要做的事情。