2017-01-23 34 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")。