Изменить 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
}
Другие вопросы по тегам