2016-09-07 21 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

正是我在找的東西,非常感謝。 –