MS SQL 2005 “Для XML Path” Вопрос о макете узла
-
22-08-2019 - |
Вопрос
У меня есть следующий запрос
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>
Я бы хотел, чтобы дочерние узлы 1 были частью узла 1, а не отдельным узлом ниже.
<Root>
<node1>
<field1>data1</field1>
<field2>data2</field2>
<child1>
<field3>data3</field3>
<field4>data4</field4>
</child1>
<child1>
...
</node1>
<node1>
...
</Root>
Я попытался поместить node1 в ПУТЬ к подзапросу
FOR XML PATH('node1'),TYPE,Elements)
или добавляя к именам полей подзапроса префикс node1
Select field3 as 'node1/child1/field3',
но оба создают новый элемент node1 для подзапроса.
Кто-нибудь знает, как я могу этого добиться?
Спасибо
Решение
Вы должны сообщить 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>
Другие советы
Я не проделал большой работы с T-SQL и для XML, но я решил аналогичную проблему, вызывая часть запроса FOR XML после каждого подзапроса, как показано ниже, и используя идентификатор ПУТИ для установки узлов:
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>
Как упоминал Андомар, вам необходимо убедиться, что ваши данные соединены правильно.
У меня также есть предложение Group By, чтобы убедиться, что данные не "сбиваются с пути".У меня возникла проблема с репликацией данных подзапроса как дочерних для каждой записи во внешнем запросе (под каждым узлом было несколько дочерних элементов, связанных с количеством имеющихся узлов).) Я уверен, что есть простое объяснение, но я работал в сжатые сроки, когда делал это, и никогда не возвращался, чтобы проверить...
Если это неправильное использование или кто-нибудь может пролить свет на повторяющиеся группы, пожалуйста, укажите на это, и я отредактирую...
Мой первый пример запроса был не совсем правильным, как вы указали.Вот более точный пример запроса.
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') во внешнем запросе.Внешние поля запроса используются во многих различных путях к узлам в корневом каталоге.Мне нужен подзапрос для повторной настройки под node1, и есть другие подзапросы, которые нужно вернуть под node2, node3...
Я очень надеюсь, что в моих словах есть смысл.Это мой первый пост, и в следующий раз я обязательно опубликую лучший пример запроса.
Спасибо за ответы.
Дирк
Возможно, будет иметь больше смысла, если вы опубликуете некоторые образцы данных, а не будете использовать node1, field1, child1 и т.д.и объясните, из каких таблиц поступают данные.
XML является иерархическим по своей природе.Вы не можете произвольно запускать новые узлы, которые не связаны с другими узлами под корнем, что, похоже, вы пытаетесь сделать.
Все , что внутри <node1>
..чтобы..</node1>
относится к одной записи и данным, сгенерированным ее подзапросами.Следующая последовательность узлов будет реплицировать структуру следующим образом <node2>
..чтобы..</node2>
для следующей записи.
Если вы хотите больше подзапросов под каждым узлом, то просто напишите каждый из них в SQL со своим собственным FOR XML PATH('SubNodeName')
Опубликуйте свой XSD или образец XML-кода, и я посмотрю, смогу ли я понять, что вы пытаетесь сделать.