Search code examples
xmlxpathxqueryxslt-2.0

How to mearge the conscutive/continued 'bold' element


Here we are try to mearge the conscutive 'bold' element i.e. '</bold><bold>' or '</bold> <bold>'. See the below example:

Note: We are not mearging if other node are coming '</bold> See <bold>'.

INPUT XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<h1><bold>Abandonment of Trade Secret</bold></h1>
<h2><bold>Abuse of Discretion.</bold> See <bold>Discretion of Court</bold></h2>
<h3>Licensing agreement, modifications to. See <bold>Licensing Agreements</bold></h3>
<h4><bold>Alternative Minimum Tax (AM</bold><bold>T)</bold></h4>
<h5><bold>Audits.</bold> See <bold>Trade Secre</bold><bold>t Audits</bold></h5>
<h6><bold>California Uniform Trade</bold><bold> Secrets Act (UTSA).</bold> See <bold>Uniform Trade Secrets Act, California (UTSA)</bold></h6>
<h7><bold>Charts, Checklists, Questionnaires, </bold><bold>and Tables</bold></h7>
<h8><bold>Competition.</bold> See <bold>Covenant Against Competition;</bold> <bold>Unfair Competition</bold></h8>
<h9>See also <bold>Internet;</bold> <bold>Websites</bold> <bold>URL</bold></h9>
<h10>See also <bold>Copyrights;</bold><bold> Intellectual Property; Patents; </bold><bold>Trademarks</bold></h10>
</root>

EXPECTED OUTPUT:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<h1><bold>Abandonment of Trade Secret</bold></h1>
<h2><bold>Abuse of Discretion.</bold> See <bold>Discretion of Court</bold></h2>
<h3>Licensing agreement, modifications to. See <bold>Licensing Agreements</bold></h3>
<h4><bold>Alternative Minimum Tax (AMT)</bold></h4>
<h5><bold>Audits.</bold> See <bold>Trade Secret Audits</bold></h5>
<h6><bold>California Uniform Trade Secrets Act (UTSA).</bold> See <bold>Uniform Trade Secrets Act, California (UTSA)</bold></h6>
<h7><bold>Charts, Checklists, Questionnaires, and Tables</bold></h7>
<h8><bold>Competition.</bold> See <bold>Covenant Against Competition; Unfair Competition</bold></h8>
<h9>See also <bold>Internet; Websites URL</bold></h9>
<h10>See also <bold>Copyrights; Intellectual Property; Patents; Trademarks</bold></h10>
</root>

XSLT CODE:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

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

<xsl:template match="*[bold]">
    <xsl:copy>
        <xsl:for-each-group select="*" group-adjacent=". instance of element(bold)">
            <xsl:choose>
                <xsl:when test="current-grouping-key()">
                    <xsl:copy>
                        <xsl:apply-templates select="current-group()/node()"/>
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Reference URL # https://xsltfiddle.liberty-development.net/gVruFNL/1


Solution

  • In this example you have mixed contents of text and element nodes so you want

        <xsl:for-each-group select="node()" group-adjacent=". instance of element(bold)">
    

    If there are also white space text nodes you want to wrap the using

    <xsl:template match="*[bold]">
        <xsl:copy>
            <xsl:for-each-group select="node()" group-adjacent=". instance of element(bold) or (. instance of text() and not(normalize-space()))">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <xsl:copy>
                            <xsl:apply-templates select="current-group()"/>
                        </xsl:copy>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="bold">
        <xsl:apply-templates/>
    </xsl:template>
    

    might suffice, although it runs the risk of failing with if the adjacent group starts with a white space text node.