Использование атрибута более одного раза в запросе FOR XML Path T-SQL с тем же именем элемента

Я пытаюсь создать вывод XML в SQL 2008, используя FOR XML Path. Это работает нормально:

<Taxonomy>
      <Category Level="1">Clothing</Category>
      <SubCategory Level="2">Jeans</SubCategory>
 </Taxonomy>

Но я бы хотел, чтобы результат был:

<Taxonomy>
      <Category Level="1">Clothing</Category>
      <Category Level="2">Jeans</Category>
</Taxonomy>

Конечно, вы можете написать следующее:

1 as 'Taxonomy/Category/@Level',
2 as 'Taxonomy/Category/@Level',
t.MainCat as 'Taxonomy/Category', 
t.SubCat as 'Taxonomy/Category',

Но это выдает сообщение об ошибке: Атрибут-ориентированный столбец 'Имя столбца повторяется. Один и тот же атрибут не может быть сгенерирован более одного раза в одном и том же теге XML.

Что можно сделать, чтобы получить желаемый результат? Подойдет ли выборочная работа или какой-нибудь крест? Или, может быть, союз? Но как?

---- РЕДАКТИРОВАТЬ - после нескольких ответов было найдено следующее решение:

SELECT 
1 as 'Category/@Level',
t.Cat as 'Category'
FROM table t

UNION

SELECT 
2 as 'Category/@Level',
t.SubCat as 'Category'
FROM table t

FOR XML PATH (''), ROOT('Taxonomy')

дает этот вывод:

<Taxonomy>
  <Category Level="1">Clothing</Category>
  <Category Level="2">Jeans</Category>
</Taxonomy>

Еще нужно выяснить, как поместить это частичное кодирование в гораздо больший код с несколькими уже "вложенными" FOR XML

3 ответа

Решение

Методы быстрого доступа не могут сократить это для этого. AUTO и PATH не любят несколько элементов с одинаковыми именами. Похоже, вам придется использовать команду FOR XML EXPLICIT.

Это работает, но громоздко.

Образец:

--Generate Sample Data
--FOR XML EXPLICIT requires two meta fields: Tag and Parent
--Tag is the ID of the current element.
--Parent is the ID of the parent element, or NULL for root element.

DECLARE @DataTable as table
   (Tag int NOT NULL
   , Parent int
   , TaxonomyValue nvarchar(max)
   , CategoryValue nvarchar(max)
   , CategoryLevel int)

--Fill with sample data: Category Element (2), under Taxonomy(1), with no Taxonomy value.
INSERT INTO @DataTable
VALUES (2, 1, NULL, 1, 'Clothing')
     , (2, 1, NULL, 2, 'Jeans')

--First part of query: Define the XML structure
SELECT
   1 as Tag  --root element
   , NULL as Parent
   , NULL as [Taxonomy!1]       --Assign Taxonomy Element to the first element, aka root.
   , NULL as [Category!2]       --Assign Category Element as a child to Taxonomy.
   , NULL as [Category!2!Level] --Give Category an Attribute 'Level'

--The actual data to fill the XML
UNION
SELECT
   Data.Tag
   , Data.Parent
   , Data.TaxonomyValue
   , Data.CategoryValue
   , Data.CategoryLevel
FROM
   @DataTable as Data
FOR XML EXPLICIT

Генерирует XML

<Taxonomy>
  <Category Level="1">Clothing</Category>
  <Category Level="2">Jeans</Category>
</Taxonomy>

Изменить: Столбцы поменялись местами. Нет больше уровня джинсов.

Я знаю, что это старый пост, но я хочу поделиться одним решением, которое позволяет избежать сложности команды FOR XML EXPLICIT для больших xmls.

Достаточно добавить нуль в качестве дочернего элемента таксономии, и ошибка исчезнет:

    select 1 as 'Taxonomy/Category/@Level',
           t.MainCat as 'Taxonomy/Category',
           NULL AS 'Taxonomy/*',
           2 as 'Taxonomy/Category/@Level',
           t.SubCat as 'Taxonomy/Category',
    from t

Я надеюсь, что это помогает.

У меня есть другой способ. Это казалось немного легким для меня. Скажем, например, у меня есть XML как

DECLARE @xml xml='<parameters></parameters>'

DECLARE @multiplenodes XML = '<test1><test2 Level="1">This is a test node 2</test2><test2 Level="2">This is another test node</test2></test1>'

SET @xml.modify('insert sql:variable("@multiplenodes") into (/parameters)[1]')

SELECT @xml

Скажи мне, если это поможет.

Другие вопросы по тегам