2017-01-23 35 views
0

我想使用XQuery對XML文檔進行排序。第一級排序是由父元素之一。在XQuery中排序:嵌套FLWOR

而第二級排序是鏈接的子元素之一。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<FEATURES xmlns="http://www.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <FEATURE> 
     <abbreviation>CANAL</abbreviation> 
     <LINKED_PROPERTIES> 
      <LP> 
       <abbreviation>zltinf</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>altalt</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>betbet</abbreviation> 
       <category>C</category> 
       <remarks /> 
      </LP> 
     </LINKED_PROPERTIES> 
     <description>Water Canal</description> 
     <code>23</code> 
     <relation_type /> 
    </FEATURE> 
    <FEATURE> 
     <abbreviation>AREA</abbreviation> 
     <LINKED_PROPERTIES> 
      <LP> 
       <abbreviation>zltzlt</abbreviation> 
       <category>A</category> 
       <remarks>zolt zolt</remarks> 
      </LP> 
      <LP> 
       <abbreviation>altalt</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>betbet</abbreviation> 
       <category>C</category> 
       <remarks /> 
      </LP> 
     </LINKED_PROPERTIES> 
     <description>Area under administration</description> 
     <code>1</code> 
     <relation_type /> 
    </FEATURE> 
    <FEATURE> 
     <abbreviation>BUOY</abbreviation> 
     <LINKED_PROPERTIES> 
      <LP> 
       <abbreviation>zltinf</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>altalt</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>betbet</abbreviation> 
       <category>C</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>infinf</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>altalt</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>betbet</abbreviation> 
       <category>C</category> 
       <remarks /> 
      </LP> 
     </LINKED_PROPERTIES> 
     <description>Buoy on water</description> 
     <code>18</code> 
     <relation_type /> 
    </FEATURE> 
    <FEATURE> 
     <abbreviation>DRONE</abbreviation> 
     <LINKED_PROPERTIES> 
      <LP> 
       <abbreviation>zltinf</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>beltam</abbreviation> 
       <category>A</category> 
       <remarks /> 
      </LP> 
      <LP> 
       <abbreviation>betbet</abbreviation> 
       <category>C</category> 
       <remarks /> 
      </LP> 
     </LINKED_PROPERTIES> 
     <description>Drones Inland</description> 
     <code>2</code> 
     <relation_type /> 
    </FEATURE> 
</FEATURES> 

本文檔包含屬於一個標準的兩個級別的功能。所以顯然我不能修改XML文檔。以上數據是匿名數據。

我的XQuery如下所示。

<FEATURES xmlns="http://www.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    { 
    let $doc := doc("features.xml") 
    for $feature in $doc/FEATURES/FEATURE 
    order by $feature/abbreviation ascending 
    return 
    <FEATURE> 
     { 
     for $ft in $feature 
     return if ($ft/child::element/name() eq 
     "LINKED_PROPERTIES")then 
     <LINKED_PROPERTIES_XXXXXXXX>{ 
      for $lp in $ft/LINKED_PROPERTIES/LP 
      order 
      by $lp/abbreviation ascending 
      return $lp 
      } 
     </LINKED_PROPERTIES_XXXXXXXX> 
     else $ft/*} 
    </FEATURE> 
    } 
</FEATURES> 

我無法在子級別獲得適當的平等條件,因此無法在子級別獲得期望的排序。

出於以下原因,我不想回到DOM/XSL。請協助。

回答

1

內部for需要迭代該特徵的子元素,否則將只有一個元素迭代。此外,在樹中進一步向下,LINKED_PROPERTIES必須被移除,因爲$ ft已經在該節點,並且其他孩子必須按照原樣返回。最後,實物測試不太正確(必須是child::element())。

<FEATURES xmlns="http://www.example.com/" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">{ 
    let $doc := doc("features.xml") 
    for $feature in $doc/FEATURES/FEATURE 
    order by $feature/abbreviation ascending 
    return <FEATURE>{ 
    for $ft-child in $feature/child::element() 
    return if ($ft-child/name() eq "LINKED_PROPERTIES") 
      then <LINKED_PROPERTIES_XXXXXXXX>{ 
      for $lp in $ft-child/LP 
      order by $lp/abbreviation ascending 
      return $lp 
      }</LINKED_PROPERTIES_XXXXXXXX> 
      else $ft-child 
    }</FEATURE> 
}</FEATURES> 

上述查詢在oXygen中成功。

+0

我試過BaseH,因爲我沒有氧氣。我觀察到的是在運行xquery後將父元素與子元素鏈接的屬性混合。 –

+0

XQuery是標準化的,它也可以與BaseX一起使用。隨意粘貼您的查詢和輸出,如果仍然有錯誤,以及您的預期輸出。我們很樂意提供幫助。 –

+0

現在正在工作! –

0

如果你的意思是測試如果FEATURE有CHID元素LINKED_PROPERTIES

return if ($ft/LINKED_PROPERTIES) then 
    <LINKED_PROPERTIES_XXXXXXXX> 
    { 
     ..... 
    } 
    </LINKED_PROPERTIES_XXXXXXXX> 

你的XQuery嘗試對同一並沒有太大的意義,因爲它會查找名爲element子元素,它永遠不會計算爲真($ft/child::element),並進一步測試元素名稱是否等於"LINKED_PROPERTIES"/name() eq "LINKED_PROPERTIES")。