2016-09-07 68 views
1

我有以下格式一些XML:树创建XML形成从平面XML使用XQuery

<data> 
    <row> 
     <id>1</id> 
     <parent_id/> 
    </row> 
    <row> 
     <id>2</id> 
     <parent_id>1</parent_id> 
    </row> 
    <row> 
     <id>3</id> 
     <parent_id>1</parent_id> 
    </row> 
    <row> 
     <id>4</id> 
     <parent_id>5</parent_id> 
    </row> 
    <row> 
     <id>5</id> 
     <parent_id/> 
    </row> 
    <row> 
     <id>6</id> 
     <parent_id>2</parent_id> 
    </row> 
    <row> 
     <id>7</id> 
     <parent_id>4</parent_id> 
    </row> 
</data> 

我试图把它弄成这个样子:

<data> 
    <row> 
    <id>1</id> 
    <children> 
     <row> 
     <id>2</id> 
     <parent_id>1</parent_id> 
     <children> 
      <id>6</id> 
      <parent_id>2</parent_id> 
      <children/> 
     </children> 
     </row> 
     <row> 
     <id>3</id> 
     <parent_id>1</parent_id> 
     <children/> 
     </row> 
    </children> 
    <parent_id/> 
    </row> 
    <row> 
    <id>5</id> 
    <parent_id/> 
    <children> 
     <row>   
      <id>4</id> 
      <parent_id>5</parent_id> 
      <children> 
      <row> 
       <id>7</id> 
       <parent_id>4</parent_id> 
       <children/> 
      </row> 
      </children> 
     </row> 
    </children> 
    </row> 
</data> 

我想如果存在多个根节点(无父母),则只将这些平面数据与父亲ID分类到多棵树中。以下所有孩子将递归添加到他们父母的<children>元素中。

我对Xquery很新,所以我可以在如何处理这种递归方面使用一些帮助。我设法产生了根级和第二级,但我应该如何缓解这一点,并考虑到每个儿童级别都可能有多条路径可以通过?作为奖励,我也会对如何以相反的方式做到这一点感兴趣:从叶子开始,在父元素内部添加一个类似的结构。

declare function local:root() { 
    let $root := doc("source.xml")/Result/Rows/Row[parent_object_id = ''] 
    return $root 
}; 

declare function local:recurse($input) { let 
    $children := doc("source.xml")/Result/Rows/Row[parent_object_id = $input/object_id] 
    return $children 
}; 

<result> 
    <object_id>{local:root()/object_id/text()}</object_id> 
    <parent_object_id>{local:root()/parent_object_id/text()} </parent_object_id> 
    <children>{local:recurse(local:root())}</children> 
</result> 
+0

嗨。你正在申请什么规则?请包含您的业务逻辑和您的代码。 –

+0

我添加了我到目前为止所提供的内容。 –

回答

0

可以使用递归函数来做到这一点:

我返回根元素及其子当前代码

declare function local:nest-children($data, $id) { 
    <row>{ 
    $id, 
    <children>{ 
     for $child in $data/row[parent_id = $id] 
     return local:nest-children($data, $child/id) 
    }</children> 
    }</row> 
}; 

<data>{ 
    for $outer in $data/row[empty(parent_id/text())] 
    return local:nest-children($data, $outer/id) 
}</data> 

这将返回以下结果:

<data> 
    <row> 
    <id>1</id> 
    <children> 
     <row> 
     <id>2</id> 
     <children> 
      <row> 
      <id>6</id> 
      <children/> 
      </row> 
     </children> 
     </row> 
     <row> 
     <id>3</id> 
     <children/> 
     </row> 
    </children> 
    </row> 
    <row> 
    <id>5</id> 
    <children> 
     <row> 
     <id>4</id> 
     <children> 
      <row> 
      <id>7</id> 
      <children/> 
      </row> 
     </children> 
     </row> 
    </children> 
    </row> 
</data> 
+0

正是我在找的东西,非常感谢。 –