我有以下格式的XML:
<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)
您可以使用递归函数来执行此操作:
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>