修改XML以按名称排序中级复杂类型元素

时间:2014-10-08 15:37:59

标签: sql xml sorting sql-server-2008-r2 xquery

修改:有关后续问题,请参阅This link

我在SQL Server 2008 R2中有一个很大的FOR XML EXPLICIT查询,它创建了一个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命令的工作方式意味着包含某些属性的每个组都是有序的(在这种情况下是底层),但我不知道如何控制直接位于其下方的属性的顺序(在这种情况下) )&#34; Thing&#34;水平。如何指定&#34; Thing&#34;的子元素?当没有SQL到ORDER BY的属性数据时,它应该按名称的字母顺序出现吗?

正如我所提到的,这是一个很大的XML,有许多不同的元素,并不总是全部出现,所以如果有某种方法可以在某个级别对所有子元素进行排序,而不会影响排序孙子元素无需对每个元素名称进行硬编码,这真的很棒。

我搜遍了整个地方,无法找到方法。我已经查看了我的XML输出上的事后xquery修改(在我看来这是最实用的解决方案,因为一些要排序的元素具有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>

正如你所看到的,下面的三个元素&#34; Thing&#34;现在按字母顺序排列(字母,数字,赛车),但每个元素中的所有元素都按顺序保持不变。

如果您希望我写出SELECT ... FOR XML EXPLICIT来生成上面的示例XML,请告诉我们。我很乐意这样做 - 我只是期望答案将直接在上面的XML上以xquery的形式出现,所以认为不太可能需要它!

1 个答案:

答案 0 :(得分:0)

您必须重建<Things/>元素,按<Thing/>的名称排序。这个片段按第一个孩子的名字排序,因为我们需要一个值来排序。关于给出的输入,似乎没有必要在<Thing/>内订购 (甚至可能是错误的)。

element Things {
  for $thing in /Things/Thing
  let $name := local-name(($thing/*)[1])
  order by $name
  return $thing
}