Search code examples
xsltxslt-2.0

How can group-adjacent - XSLT


How can group-adjacent if the before year same text next paragraph then group move to descending order e.g. AFL-CIO v Unemployment Ins. Appeals Bd. (1994), AFL-CIO v Unemployment Ins. Appeals Bd. (1996) and ATPAC, move to after this text ATS Prods., Inc. v Champion Fiberglass,.
Input XML

<root>
<p content-type="emLetHead">A</p>
<p content-type="emCase"><named-content content-type="emEntry">A.M. v Albertsons, LLC (2009) 178 CA4th 455:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ABBA Rubber Co. v Seaquist (1991) 235 CA3d 1:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ABC Int&#x2019;l Traders, Inc. v Matsushita Elec. Corp. (1997) 14 C4th 1247:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">AFL-CIO v Unemployment Ins. Appeals Bd. (1994) 23 CA4th 51:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">AFL-CIO v Unemployment Ins. Appeals Bd. (1996) 13 C4th 1017:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATPAC, Inc. v Aptitude Solutions, Inc. (ED Cal, Apr. 29, 2010, No. CIV. 2:10&#x2013;294 WBS KJM) 2010 US Dist Lexis 42109:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATS Prods., Inc. v Champion Fiberglass, Inc. (ND Cal, Jan. 15, 2015, No. 13&#x2013;cv&#x2013;02403&#x2013;SI) 2015 US Dist Lexis 5106:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATS Prods., Inc. v Champion Fiberglass, Inc. (ND Cal, Nov. 19, 2013, No. C 13-02403 SI) 2013 US Dist Lexis 13886:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Abadia-Peixoto v U.S. Dep&#x2019;t of Homeland Sec. (ND Cal, Aug. 23, 2013, No. 11-cv-04001 RS (KAW)) 2013 US Dist Lexis 120368:</named-content></p>
</root>

XSL CODE

    <xsl:template match="root">
    <xsl:copy>
        <xsl:for-each-group select="p" group-adjacent="named-content[@content-type='emEntry']">
            <xsl:choose>
                <xsl:when test="current-grouping-key()">
                    <xsl:apply-templates select="current-group()">
                        <xsl:sort select="number(contains(named-content[@content-type='emEntry'], '(.+)\(([0-9]+)'))" data-type="number" order="descending"/>
                    </xsl:apply-templates>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

Expected output

<root>
<p content-type="emLetHead">A</p>
<p content-type="emCase"><named-content content-type="emEntry">A.M. v Albertsons, LLC (2009) 178 CA4th 455:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ABBA Rubber Co. v Seaquist (1991) 235 CA3d 1:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ABC Int&#x2019;l Traders, Inc. v Matsushita Elec. Corp. (1997) 14 C4th 1247:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">AFL-CIO v Unemployment Ins. Appeals Bd. (1996) 13 C4th 1017:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">AFL-CIO v Unemployment Ins. Appeals Bd. (1994) 23 CA4th 51:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATS Prods., Inc. v Champion Fiberglass, Inc. (ND Cal, Jan. 15, 2015, No. 13&#x2013;cv&#x2013;02403&#x2013;SI) 2015 US Dist Lexis 5106:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATS Prods., Inc. v Champion Fiberglass, Inc. (ND Cal, Nov. 19, 2013, No. C 13-02403 SI) 2013 US Dist Lexis 13886:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">ATPAC, Inc. v Aptitude Solutions, Inc. (ED Cal, Apr. 29, 2010, No. CIV. 2:10&#x2013;294 WBS KJM) 2010 US Dist Lexis 42109:</named-content></p>
<p content-type="emCase"><named-content content-type="emEntry">Abadia-Peixoto v U.S. Dep&#x2019;t of Homeland Sec. (ND Cal, Aug. 23, 2013, No. 11-cv-04001 RS (KAW)) 2013 US Dist Lexis 120368:</named-content></p>
</root>

Solution

  • I think you want to group adjacent elements on the substring before the ( and then you want to extract the year to sort inside of a group, here is an XSLT 3 sample using the analyze-string function (if you are restricted to XSLT 2 use the same approach but the xsl:analyze-string element instead inside of the function to extract the date):

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:mf="http://example.com/mf"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:output indent="yes"/>
    
      <xsl:function name="mf:extract-year" as="xs:integer?">
          <xsl:param name="input" as="xs:string"/>
          <xsl:sequence
             select="analyze-string($input, '\(.*?([0-9]{4}).*\)')/*:match/*:group[@nr = 1]/xs:integer(.)"/>
      </xsl:function>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:template match="root">
          <xsl:copy>
              <xsl:for-each-group select="p" group-adjacent="substring-before(named-content[@content-type = 'emEntry'], '(')">
                    <xsl:apply-templates select="current-group()">
                        <xsl:sort select="let $year := mf:extract-year(.)
                                          return if ($year) then -$year else 1"/>
                    </xsl:apply-templates>
              </xsl:for-each-group>
          </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/naZXVFc