Xquery 帮助排序父子关系 [英] Xquery help sorted parent child relationship

查看:35
本文介绍了Xquery 帮助排序父子关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 xml(从实际输入中简化和匿名化)它基本上包含一个策略列表,这些策略具有策略开始日期、策略参考和父策略参考(0 表示没有父策略)

I have the below xml (simplified and anonymized from real input) it basically contains a list of policies which have a policy start date, policy reference, and a parent policy reference (with 0 indicating no parent)

我想要实现的是表单的输出.

What I am trying to achieve is the output of the form.

  • 最旧的策略在顶部(最旧的开始日期)
    • 如果它有孩子,它的孩子必须跟随(也按最早的开始日期排序)
    • 如果它有孩子,它的孩子必须跟随(也按最早的开始日期排序)

    它实际上让我难住了,我尝试了各种方法,但这是我最近的尝试.

    It actually has me stumped, I've tried various things, but here is my latest attempt.

    {
    let $rows:= for $x in SOAP-ENV:Envelope/SOAP-ENV:Body/cus:GetCustPolicyResponse/cus:Policy/cus:PolicyRow
    order by $x/cus:DateStart
    return $x
    for$policy in distinct-values($rows/cus:PolRef)
    for $parentPolicy in distinct-values($rows/cus:parentPolRef)
            for $row in $rows
            where $row/cus:parentPolRef =$parentPolicy  and $row/cus:PolRef =$policy
            return <tr>
                    <td>{$row/cus:PolRef/text()}</td>
                    <td>{$row/cus:parentPolRef/text()}</td>
                    <td>{$row/cus:DateStart/text()}</td>
                    </tr>
    }
    

    XML

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="hp://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="hp://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="hp://www.w3.org/2001/XMLSchema">
       <SOAP-ENV:Body>
          <GetCustPolicyResponse xmlns="hp://www.client.com/services/customer">
             <Policy>
                <PolicyRow>
                   <PolRef>1</PolRef>
                   <DateStart>2011-04-01</DateStart>
                   <parentPolRef>0</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>2</PolRef>
                   <DateStart>2011-04-01</DateStart>
                   <parentPolRef>0</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>3</PolRef>
                   <DateStart>2011-04-20</DateStart>
                   <parentPolRef>0</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>20</PolRef>
                   <DateStart>2011-04-02</DateStart>
                   <parentPolRef>1</parentPolRef>
                </PolicyRow>
                 <PolicyRow>
                   <PolRef>21</PolRef>
                   <DateStart>2011-04-01</DateStart>
                   <parentPolRef>1</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>26</PolRef>
                   <DateStart>2011-04-22</DateStart>
                   <parentPolRef>3</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>4</PolRef>
                   <DateStart>2011-04-03</DateStart>
                   <parentPolRef>0</parentPolRef>
                </PolicyRow>
            <PolicyRow>
                   <PolRef>25</PolRef>
                   <DateStart>2011-04-21</DateStart>
                   <parentPolRef>3</parentPolRef>
                </PolicyRow>
                <PolicyRow>
                   <PolRef>24</PolRef>
                   <DateStart>2011-04-16</DateStart>
                   <parentPolRef>2</parentPolRef>
                </PolicyRow>
                 <PolicyRow>
                   <PolRef>23</PolRef>
                   <DateStart>2011-04-17</DateStart>
                   <parentPolRef>2</parentPolRef>
                </PolicyRow>
             </Policy>
          </GetCustPolicyResponse>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    想要的输出

    <table>
    <tr>
        <td>Policy Reference</td>
        <td>Policy start date</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2011-04-01</td>
    </tr>
    <tr>
        <td>21</td>
        <td>2011-04-21</td>
    </tr>
    <tr>
        <td>20</td>
        <td>2011-04-02</td>
    </tr>
    <tr>
        <td>2</td>
        <td>2011-04-01</td>
    </tr>
    <tr>
        <td>24</td>
        <td>2011-04-16</td>
    </tr>
    <tr>
        <td>23</td>
        <td>2011-04-17</td>
    </tr>
    <tr>
        <td>4</td>
        <td>2011-04-03</td>
    </tr>
    <tr>
        <td>3</td>
        <td>2011-04-20</td>
    </tr>
    <tr>
        <td>25/td>
        <td>2011-04-21</td>
    </tr>
    <tr>
        <td>26</td>
        <td>2011-04-22</td>
    </tr>
    

    推荐答案

    I.此 XQuery 代码:

    declare namespace  x = "hp://www.client.com/services/customer";  
    declare function x:PolicyByParentRef($pNodes as element()*, 
                                         $pRef as xs:string) as element()*
    {
      $pNodes[x:parentPolRef eq $pRef]
    };
    
    declare function x:ProcessPolicy($pNodes as element()*, 
                                     $pPol as element()) as element()*
    {
     if(not(empty($pPol)))
       then  
        (<tr>
            <td>{$pPol/x:PolRef/text()}</td>,
            <td>{$pPol/x:DateStart/text()}</td>
          </tr>,
         for $child-policy in x:PolicyByParentRef($pNodes, $pPol/x:PolRef)
           order by $child-policy/x:DateStart descending
           return
                x:ProcessPolicy($pNodes, $child-policy)
        )
      else ()
    };
    <table>
    {for $topPolicy in  x:PolicyByParentRef(/*/*/*/*/x:PolicyRow,  '0')
        order by $topPolicy/x:DateStart  descending
       return
           x:ProcessPolicy(/*/*/*/*/x:PolicyRow, $topPolicy)
     }
    </table>
    

    应用于提供的 XML 文档时:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="hp://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="hp://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="hp://www.w3.org/2001/XMLSchema">
      <SOAP-ENV:Body>
        <GetCustPolicyResponse xmlns="hp://www.client.com/services/customer">
          <Policy>
            <PolicyRow>
              <PolRef>1</PolRef>
              <DateStart>2011-04-01</DateStart>
              <parentPolRef>0</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>2</PolRef>
              <DateStart>2011-04-01</DateStart>
              <parentPolRef>0</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>3</PolRef>
              <DateStart>2011-04-20</DateStart>
              <parentPolRef>0</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>20</PolRef>
              <DateStart>2011-04-02</DateStart>
              <parentPolRef>1</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>21</PolRef>
              <DateStart>2011-04-01</DateStart>
              <parentPolRef>1</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>26</PolRef>
              <DateStart>2011-04-22</DateStart>
              <parentPolRef>3</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>4</PolRef>
              <DateStart>2011-04-03</DateStart>
              <parentPolRef>0</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>25</PolRef>
              <DateStart>2011-04-21</DateStart>
              <parentPolRef>3</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>24</PolRef>
              <DateStart>2011-04-16</DateStart>
              <parentPolRef>2</parentPolRef>
            </PolicyRow>
            <PolicyRow>
              <PolRef>23</PolRef>
              <DateStart>2011-04-17</DateStart>
              <parentPolRef>2</parentPolRef>
            </PolicyRow>
          </Policy>
        </GetCustPolicyResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    产生想要的结果:

    <?xml version="1.0" encoding="UTF-8"?>
    <table>
       <tr>
          <td>3</td>,
            <td>2011-04-20</td>
       </tr>
       <tr>
          <td>26</td>,
            <td>2011-04-22</td>
       </tr>
       <tr>
          <td>25</td>,
            <td>2011-04-21</td>
       </tr>
       <tr>
          <td>4</td>,
            <td>2011-04-03</td>
       </tr>
       <tr>
          <td>1</td>,
            <td>2011-04-01</td>
       </tr>
       <tr>
          <td>20</td>,
            <td>2011-04-02</td>
       </tr>
       <tr>
          <td>21</td>,
            <td>2011-04-01</td>
       </tr>
       <tr>
          <td>2</td>,
            <td>2011-04-01</td>
       </tr>
       <tr>
          <td>23</td>,
            <td>2011-04-17</td>
       </tr>
       <tr>
          <td>24</td>,
            <td>2011-04-16</td>
       </tr>
    </table>
    

    二.仅供比较 - XSLT 解决方案:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:x="hp://www.client.com/services/customer"
     exclude-result-prefixes="x">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:key name="kPolicyByRef" match="x:PolicyRow"
      use="x:parentPolRef"/>
    
     <xsl:template match="/">
      <table>
       <xsl:apply-templates select=
        "key('kPolicyByRef', '0')">
         <xsl:sort select="x:DateStart" order="descending"/>
       </xsl:apply-templates>
      </table>
     </xsl:template>
    
     <xsl:template match="x:PolicyRow">
      <tr>
        <xsl:apply-templates/>
      </tr>
    
      <xsl:apply-templates select=
      "key('kPolicyByRef', x:PolRef)">
       <xsl:sort select="x:DateStart" order="descending"/>
      </xsl:apply-templates>
     </xsl:template>
    
     <xsl:template match="x:PolicyRow/*">
      <td><xsl:value-of select="."/></td>
     </xsl:template>
    
     <xsl:template match="x:parentPolRef" priority="2"/>
    </xsl:stylesheet>
    

    这篇关于Xquery 帮助排序父子关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆