通过所有元素和属性使用XQuery

时间:2013-12-17 15:38:14

标签: sql sql-server xml xquery sqlxml

我仍然有一个关于通过XQuery排序xml的问题。

请检查以下代码。

原样:

<Main name = "test">
    <Sample id="1">
      <cal>
        <tree abc="123"/>
        <tree abc="789/>
        <tree-order abc="456/>
      </cal>
    </Sample>

     <Sample id="2">
      <cal>
        <tree abc="123"/>
        <tree abc="789/>
        <tree-order abc="456/>
      </cal>
    </Sample>

    <Sample id="3">
      <cal>
        <tree abc="123"/>
        <tree abc="789/>
        <tree-order abc="456/>
      </cal>
    </Sample>

</Main>

我想按属性“abc”

订购

成为1:

<Main name = "test">
    <Sample id="1">
      <cal>
        <tree abc="123"/>
        <tree-order abc="456/>
        <tree abc="789/>
      </cal>
    </Sample>

     <Sample id="2">
      <cal>
        <tree abc="123"/>
        <tree-order abc="456/>
        <tree abc="789/>
      </cal>
    </Sample>

    <Sample id="3">
      <cal>
        <tree abc="123"/>
        <tree-order abc="456/>
        <tree abc="789/>
      </cal>
    </Sample>
</Main>

之后可以删除属性??

最终

<Main name = "test">
    <Sample id="1">
      <cal>
        <tree />
        <tree-order />
        <tree />
      </cal>
    </Sample>

     <Sample id="2">
      <cal>
        <tree />
        <tree-order />
        <tree />
      </cal>
    </Sample>

    <Sample id="3">
      <cal>
        <tree />
        <tree-order />
        <tree />
      </cal>
    </Sample>
</Main>
像这样。

所以属性abc仅用于排序。

我试着喜欢这个

select @data.query('for $j in * order by number($j/@abc) return $j ')

然后它将显示xml格式而不进行排序。

有什么方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

以递归方式处理XML,以便您可以对<cal>元素子元素执行排序并保留其祖先结构:

declare function local:sort(
  $xml as element(cal)
) as element()
{
  element cal {
    for $e in $xml/*
    order by $e/@abc
    return local:dispatch($e)
  }
};

declare function local:remove-atts(
  $xml as element()
) as element()
{
  element { node-name($xml) } {
    $xml/@* except $xml/@abc,
    $xml/node()
  }
};

declare function local:dispatch(
  $xml as element()
) as element()
{
  typeswitch ($xml)
    case element(cal) return local:sort($xml)
    case element(tree) return local:remove-atts($xml)
    case element(tree-order) return local:remove-atts($xml)
    default return local:process($xml)
};

declare function local:process(
  $xml as element()
) as element()
{
  element { node-name($xml) } {
    $xml/@*, 
    for $n in $xml/node()
    return local:dispatch($n)
  }
};

local:process($xml)