Search code examples
xsltxslt-2.0

If start text "((^U.S. ex rel )|(^Will of ))" and contains text 'v' then how to add text before 'v' - XSLT


If Start text ((^U.S. ex rel )|(^Will of )) and contains text v then how to Insert start text ((^U.S. ex rel )|(^Will of )) before v text other wise Insert text end?
Input XML

<root>
    <p><italic>U.S. ex rel Alcohol Found. v Kalmanovitz</italic> (SD NY 2002) 186 F Supp 2d 458</p>
    <p><italic>U.S. ex rel Guardiola v Renown Health</italic> (D Nev, Aug. 25, 2015, No. 3:12&#x2013;cv&#x2013;00295-LRH-VPC) 2015 US Dist Lexis 112511</p>
    <p><italic>Will of Guardiola Renown Health</italic> (D Nev, Aug. 25, 2015, No. 3:12&#x2013;cv&#x2013;00295-LRH-VPC) 2015 US Dist Lexis 112511</p>
</root>

Expected Output

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="italic">
    <xsl:analyze-string select="." regex="((^U.S. ex rel )|(^Will of ))(.+)">
        <xsl:matching-substring>
            <xsl:value-of select="normalize-space(concat(regex-group(4), ', ', regex-group(1)))"/>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
            <xsl:value-of select="."/>
        </xsl:non-matching-substring>
    </xsl:analyze-string>
</xsl:template>

Expect Output

 <root>
    <p>Alcohol Found., U.S. ex rel v Kalmanovitz (SD NY 2002) 186 F Supp 2d 458</p>
    <p>Guardiola, U.S. ex rel v Renown Health (D Nev, Aug. 25, 2015, No. 3:12–cv–00295-LRH-VPC) 2015 US Dist Lexis 112511</p>
    <p>Guardiola Renown Health, Will of (D Nev, Aug. 25, 2015, No. 3:12–cv–00295-LRH-VPC) 2015 US Dist Lexis 112511</p>
</root>

Code:-https://xsltfiddle.liberty-development.net/3NSTbfj/23


Solution

  • Try whether

    <xsl:param name="pattern1" as="xs:string">((^U\.S\. ex rel )|(^Will of ))</xsl:param>
    
    <xsl:param name="pattern2" as="xs:string">([^v]*?)( v.*)</xsl:param>
    
    <xsl:param name="pattern3" as="xs:string" select="$pattern1 || $pattern2"/>
    
    <xsl:output method="xml"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="italic">
        <xsl:value-of select="replace(., $pattern1 || '(.*)', '$4, $2$3')"/>
    </xsl:template>
    
    <xsl:template match="italic[matches(., $pattern3)]">
        <xsl:value-of select="replace(., $pattern3, '$4, $2$3$5')"/>
    </xsl:template>
    

    helps: https://xsltfiddle.liberty-development.net/3NSTbfj/25

    You might need to normalize-space the replace result of fix the patterns. Also || is XPath 3.1, use the concat function for XPath/XSLT 2.0.