1

我想按元素的名称在某个级别重新排序某些 xml 的所有元素,但我遇到了一些麻烦。这是我正在使用的示例 xml 输出(我在 SQL Server 2008 R2 的变量 @XML 中使用它:

<Data>
  <Uns>
    <Orgs>
      <Prods>
        <Prod>
          <Something>1</Something>
          <Cars>
            <Car>
              <Number>2013213</Number>
              <BasicInfo>
                <FirstName>Bob</FirstName>
                <LastName>Monkhouse</LastName>
              </BasicInfo>
              <Anything>654</Anything>
            </Car>
            <Car>
              <Number>2013213</Number>
              <BasicInfo>
                <FirstName>Bob</FirstName>
                <LastName>Monkhouse</LastName>
              </BasicInfo>
              <Anything>654</Anything>
            </Car>
          </Cars>
        </Prod>
        <Prod>
          <Cars>
            <Car>
              <Number>2013213</Number>
              <BasicInfo>
                <FirstName>Bob</FirstName>
                <LastName>Monkhouse</LastName>
              </BasicInfo>
              <Anything>654</Anything>
            </Car>
          </Cars>
        </Prod>
       </Prods>
    </Orgs>
  </Uns>
</Data>

我想<Cars>按字母顺序修改所有子元素的顺序(在上面的示例中),使其内容保持不变。在对另一个问题的一些帮助之后,答案给出了想法,但是出现了一个错误,我让自己完全扭曲了,尝试了各种各样的变化:

select @XML.query('element Cars {
  for $anything in //Car
  order by local-name($anything/*[1])
  return $anything
}')

但似乎没有任何效果。我发现我经常遇到这三个问题的组合:显示“不支持 XQuery 语法 '/function()'”的错误,丢失所有父元素(如上例所示)或在一切都发生在订单上(再次如上)。我担心我应该使用SET @XML.modify()而不是SELECT @XML.query(),但这会导致更少的结果。

我在互联网上进行了大量的拖网搜索,但我发现的所有网站似乎都没有对 xquery FLWOR 语法提供非常完整的理解——只给出了具体且通常很简单的示例,这些示例并没有帮助我找到关于为什么这不像我希望的那样表现的解决方案。

以下是转换后上述 xml 的理想外观(Number、BasicInfo 和任何东西的顺序更改为按字母顺序):

<Data>
  <Uns>
    <Orgs>
      <Prods>
        <Prod>
            <Something>1</Something>
          <Cars>
            <Car>
              <Anything>654</Anything>
              <BasicInfo>
                <Name>Bob</Name>
              </BasicInfo>
              <Number>2013213</Number>
            </Car>
            <Car>
              <Anything>654</Anything>
              <BasicInfo>
                <Name>Bob</Name>
              </BasicInfo>
              <Number>2013213</Number>
            </Car>
          </Cars>
        </Prod>
        <Prod>
          <Cars>
            <Car>
              <Anything>654</Anything>
              <BasicInfo>
                <Name>Bob</Name>
              </BasicInfo>
              <Number>2013213</Number>
            </Car>
          </Cars>
        </Prod>
       </Prods>
    </Orgs>
  </Uns>
</Data>

非常感谢任何帮助和建议;我将继续在网上搜索以更全面地了解语法以及它到底在做什么,但在这个阶段获得某种结果将是一个真正的提升!

谢谢!

4

1 回答 1

1

您想对每个<Car/>元素中的元素重新排序,因此需要两个for循环。以下应该有效:

for $car in //Car
return <Car>{
  for $el in $car/*
  order by local-name($el)
  return $el
}</Car>

您将不得不重建父元素,因为 XQuery 不能修改现有节点(您需要 XQuery 更新,我非常怀疑 SQL Server 2008 是否支持)。

但是,请注意,我很难想象您的重新排序可能用于什么。它表示与以前完全相同的信息,并且每个 XML 解析器都不应该有所作为。我从来没有见过有人想简单地重新排序节点,通常它会为节点的相同值完成(例如重新排序元素,以便最昂贵的元素排在第一位)。

于 2014-10-09T14:09:12.027 回答