Изменить XML, чтобы упорядочить элементы сложного типа среднего уровня по имени
Изменить: см. Эту ссылку для последующего вопроса
У меня большой FOR XML EXPLICIT
запрос в SQL Server 2008 R2, который создает файл XML, но не удается выполнить проверку по моей схеме XSD, поскольку некоторые элементы среднего уровня отображаются в неправильном порядке. Вот пример XML-файла, чтобы показать, что я имею в виду:
<Things>
<Thing>
<Racecars>
<Racecar>
<Colour>Red</Colour>
<Rockets>Y</Rockets>
</Racecar>
<Racecar>
<Colour>Blue</Colour>
<Rockets>N</Rockets>
</Racecar>
</Racecars>
</Thing>
<Thing>
<Numbers>
<Number>
<NumericName>1</NumericName>
<WrittenName>One</WrittenName>
</Number>
<Number>
<NumericName>2</NumericName>
<WrittenName>Two</WrittenName>
</Number>
</Numbers>
</Thing>
<Thing>
<Letters>
<Letter>
<AlphaName>A</AlphaName>
<PhoneticName>Ay</PhoneticName>
</Letter>
<Letter>
<AlphaName>B</AlphaName>
<PhoneticName>Bee</PhoneticName>
</Letter>
</Letters>
</Thing>
</Things>
То, как работает команда XML EXPLICIT, означает, что каждая группа, содержащая некоторые атрибуты, находится в порядке (нижний уровень в данном случае), но я не знаю, как управлять порядком атрибутов непосредственно под (в данном случае) "Вещью". "Уровень. Как я могу указать, что дочерние элементы "Thing" должны отображаться в алфавитном порядке по имени, когда нет данных атрибута для SQL для ORDER BY?
Как я уже упоминал, это большой кусок XML со множеством различных элементов, которые не всегда все появляются, поэтому, если бы был какой-то способ упорядочить все дочерние элементы на определенном уровне, не влияя на порядок элементов внука без необходимости жестко кодировать каждое имя элемента, это было бы здорово.
Я искал повсюду безрезультатно для метода. Я рассмотрел как модификацию xquery ex post facto в моем выводе XML (что представляется мне наиболее практичным решением, так как некоторые из элементов, которые должны быть отсортированы, имеют minOccurs = 0), так и как часть разработки команды FOR XML EXPLICIT (что кажется наиболее эффективным, поскольку этот способ скорее предотвращает, чем устраняет ошибку), но, насколько я понял, кажется, что ничего не работает.
Я мог бы, конечно, удалить ограничения из файла схемы, но я бы предпочел избежать этого, если это вообще возможно, поскольку уступка неточности кажется неправильным направлением шага.
С приведенным выше файлом, это результат, который я считаю идеальным:
<Things>
<Thing>
<Letters>
<Letter>
<AlphaName>A</AlphaName>
<PhoneticName>Ay</PhoneticName>
</Letter>
<Letter>
<AlphaName>B</AlphaName>
<PhoneticName>Bee</PhoneticName>
</Letter>
</Letters>
</Thing>
<Thing>
<Numbers>
<Number>
<NumericName>1</NumericName>
<WrittenName>One</WrittenName>
</Number>
<Number>
<NumericName>2</NumericName>
<WrittenName>Two</WrittenName>
</Number>
</Numbers>
</Thing>
<Thing>
<Racecars>
<Racecar>
<Colour>Red</Colour>
<Rockets>Y</Rockets>
</Racecar>
<Racecar>
<Colour>Blue</Colour>
<Rockets>N</Rockets>
</Racecar>
</Racecars>
</Thing>
</Things>
Как вы можете видеть, три элемента ниже "Вещи" теперь сортируются в алфавитном порядке (буквы, цифры, гоночные машины), но все элементы в каждом из них неизменны по порядку.
Пожалуйста, дайте мне знать, если вы хотите, чтобы я выписал SELECT ... FOR XML EXPLICIT
сгенерировать пример XML выше; Я с удовольствием сделаю это - я просто ожидал, что ответ будет в форме xquery непосредственно на XML выше, так что подумал, что это вряд ли понадобится!
1 ответ
Вы должны восстановить <Things/>
элементы, упорядоченные по <Thing/>
имя Этот фрагмент кода сортирует по имени первого потомка, так как нам нужно одно значение для сортировки после. Что касается данного ввода, то нет необходимости заказывать внутри <Thing/>
(и может даже ошибаться).
element Things {
for $thing in /Things/Thing
let $name := local-name(($thing/*)[1])
order by $name
return $thing
}