#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    1
    Rep Power
    0

    Merging 2 consecutive List items in XSLT


    Hi all,

    I have a XML which has list items like

    <list type="expl" margin="0">
    <li label="(1)">
    <p num="n">
    <text>
    (1) A person
    is guilty of an offence if:
    </text>
    </p>
    </li>
    </list>
    <list type="expl" margin="0">
    <li label="(a)">
    <p num="n">
    <text>
    (a) the
    person deals with money or other property; and
    </text>
    </p>
    </li>
    </list>


    The output i need is like

    <list type="expl">
    <li label="(1)">
    <p num="n">
    <text>A person is guilty of an offence if:</text>
    </p>
    <list type="expl">
    <li label="(a)">
    <p num="n">
    <text>the person deals with money or other property; and</text>
    </p>
    </li>
    </list>
    </list>

    Effectively if List appears as consecutive siblings, and they are of different types (eg, (1)/(a)/(i)) they must be nested inside the previous list item.

    Thanks
    Srini
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2006
    Posts
    24
    Rep Power
    0
    use xslt 2.0 for-each-group and group <list> by list/li/@label

    based the output wanted:
    removes @margin and replaces newline with space in p/text/text()

    below sorts by list/li/@label, too

    input.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <list type="expl" margin="0">
        <li label="(1)">
          <p num="n">
            <text>
    (1) A person
    is guilty of an offence if:
    </text>
          </p>
        </li>
      </list>
      <list type="expl" margin="0">
        <li label="(i)">
          <p num="n">
            <text>
    (i) the
    person deals with money or other property; and
    </text>
          </p>
        </li>
      </list>
      <list type="expl" margin="0">
        <li label="(a)">
          <p num="n">
            <text>
    (a) the
    person deals with money or other property; and
    </text>
          </p>
        </li>
      </list>
      <list type="expl" margin="0">
        <li label="(1)">
          <p num="n">
            <text>
    (1) A person
    is guilty of an offence if:
    </text>
          </p>
        </li>
      </list>
      <list type="expl" margin="0">
        <li label="(a)">
          <p num="n">
            <text>
    (a) the
    person deals with money or other property; and
    </text>
          </p>
        </li>
      </list>
      <list type="expl" margin="0">
        <li label="(i)">
          <p num="n">
            <text>
    (i) the
    person deals with money or other property; and
    </text>
          </p>
        </li>
      </list>
    </root>
    xsl

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    
    	<xsl:output method="xml" indent="yes"/>
    	<xsl:variable name="__newline__" select="'&amp;#xA;'"/>
    
    	<xsl:template match="/">
        <xsl:element name="root">
          <xsl:apply-templates select="node()|@*"/>
         </xsl:element>
    	</xsl:template>
    	
    	<xsl:template match="root">
          <xsl:for-each-group select="list" group-by="child::li/@label">
              <xsl:sort select="child::li/@label" order="ascending"/>
              <xsl:for-each select="current-group()"> 
                <xsl:copy>
                  <xsl:apply-templates select="node()|@*"/>
                </xsl:copy>
              </xsl:for-each>
          </xsl:for-each-group>
    	</xsl:template>
    	
    	<xsl:template match="*|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    	</xsl:template>
    	
      <xsl:template match="text()">
        <xsl:value-of select="translate(.,$__newline__, ' ')"/>
      </xsl:template>
    
    	<xsl:template match="@margin"/>
    
    </xsl:stylesheet>
    output

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
    	<list type="expl">
    		<li label="(i)">
    			<p num="n">
    				<text> (i) the person deals with money or other property; and </text>
    			</p>
    		</li>
    	</list>
    	<list type="expl">
    		<li label="(i)">
    			<p num="n">
    				<text> (i) the person deals with money or other property; and </text>
    			</p>
    		</li>
    	</list>
    	<list type="expl">
    		<li label="(a)">
    			<p num="n">
    				<text> (a) the person deals with money or other property; and </text>
    			</p>
    		</li>
    	</list>
    	<list type="expl">
    		<li label="(a)">
    			<p num="n">
    				<text> (a) the person deals with money or other property; and </text>
    			</p>
    		</li>
    	</list>
    	<list type="expl">
    		<li label="(1)">
    			<p num="n">
    				<text> (1) A person is guilty of an offence if: </text>
    			</p>
    		</li>
    	</list>
    	<list type="expl">
    		<li label="(1)">
    			<p num="n">
    				<text> (1) A person is guilty of an offence if: </text>
    			</p>
    		</li>
    	</list>
    </root>
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2006
    Posts
    24
    Rep Power
    0
    below collects all <li> elements under same <list>; I think that is closer to what you want

    xsl
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    
    	<xsl:output method="xml" indent="yes"/>
    	<xsl:variable name="__newline__" select="'&amp;#xA;'"/>
    
    	<xsl:template match="/">
        <xsl:element name="root">
          <xsl:apply-templates select="node()|@*"/>
         </xsl:element>
    	</xsl:template>
    	
    	<xsl:template match="root">
        <xsl:variable name="_list_" select="list"/>
            <xsl:for-each-group select="list/li" group-by="@label">
              <xsl:sort select="child::li/@label" order="ascending"/>
               <xsl:element name="list">
                 <xsl:apply-templates select="$_list_"/>
                  <xsl:for-each select="current-group()"> 
                    <xsl:copy>
                      <xsl:apply-templates select="node()|@*"/>
                    </xsl:copy>
                  </xsl:for-each>
               </xsl:element>
            </xsl:for-each-group>
    	</xsl:template>
    	
    	<xsl:template match="*|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    	</xsl:template>
    	
      <xsl:template match="text()">
        <xsl:value-of select="translate(.,$__newline__, ' ')"/>
      </xsl:template>
      
      <xsl:template match="list">
        <xsl:apply-templates select="@*"/>
      </xsl:template>
    
    	<xsl:template match="@margin"/>
    
    </xsl:stylesheet>
    result
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <root>
      <list type="expl">
        <li label="(1)">
          <p num="n">
            <text> (1) A person is guilty of an offence if: </text>
          </p>
        </li>
        <li label="(1)">
          <p num="n">
            <text> (1) A person is guilty of an offence if: </text>
          </p>
        </li>
      </list>
      <list type="expl">
        <li label="(i)">
          <p num="n">
            <text> (i) the person deals with money or other property; and </text>
          </p>
        </li>
        <li label="(i)">
          <p num="n">
            <text> (i) the person deals with money or other property; and </text>
          </p>
        </li>
      </list>
      <list type="expl">
        <li label="(a)">
          <p num="n">
            <text> (a) the person deals with money or other property; and </text>
          </p>
        </li>
        <li label="(a)">
          <p num="n">
            <text> (a) the person deals with money or other property; and </text>
          </p>
        </li>
      </list>
    </root>

IMN logo majestic logo threadwatch logo seochat tools logo