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>
II. Просто для сравнения - решение 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>