OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   Re: [xml-dev] Generating implicit wrapper element

[ Lists Home | Date Index | Thread Index ]
  • To: Ferdinand Soethe <xml-dev@soethe.net>, xml-dev@lists.xml.org
  • Subject: Re: [xml-dev] Generating implicit wrapper element
  • From: Mukul Gandhi <mukul_gandhi@yahoo.com>
  • Date: Tue, 30 Aug 2005 07:50:43 -0700 (PDT)
  • Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Message-ID:Received:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding; b=1+iFSPRhE8yYrKc3omE9xQsNoxldZdL4xZezmdG0RlKHpvoVvb/2wsu95zyXy96EiVBQyqNeqmNPtTSRRf6J93IRrdXoambXaMkWONzPvXFXIb4MV+P7FLM7poGKIBZn6oeH5fL04fNq9S4sAieNeaH4UX8eH6RG1pXGwVAtN3Y= ;
  • In-reply-to: <14310060524.20050830145620@soethe.net>

Please try this XSLT stylesheet

<?xml version="1.0"?> 
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
 
<xsl:output method="xml" indent="yes" /> 
 
<xsl:template match="/root">
   <root>
    <xsl:for-each select="*">
      <xsl:choose>
        <xsl:when test="self::par">
         <p><xsl:value-of select="." /></p>
        </xsl:when>
        <xsl:otherwise>          
          <xsl:if test="(name(preceding-sibling::*[1])
= 'par') or (position() = 1)">
            <ul>
              <xsl:call-template name="makegroup">    
         
                <xsl:with-param name="nodeset"
select="self::* | following-sibling::*" />
              </xsl:call-template>
            </ul>  
          </xsl:if>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
   </root>
</xsl:template>

<xsl:template name="makegroup">
   <xsl:param name="nodeset" />
   
   <xsl:if test="name($nodeset[1]) = 'li'">
     <xsl:copy-of select="$nodeset[1]" />
     <xsl:call-template name="makegroup">             

       <xsl:with-param name="nodeset"
select="$nodeset[position() &gt; 1]" />
     </xsl:call-template>
   </xsl:if>
   
</xsl:template>
 
</xsl:stylesheet>

For e.g. when it is applied to XML
<root>
  <par>my first para</par>
  <par>second para</par>
  <li>first list item of first list</li>
  <li>second list item of first list</li>
  <li>third list item of first list</li>
  <par>third para</par>
  <li>first list item of second list</li>
  <par>fourth para</par>
  <li>first list item of third list</li>
  <li>second list item of third list</li>
</root>

The output produced is
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <p>my first para</p>
  <p>second para</p>
  <ul>
    <li>first list item of first list</li>
    <li>second list item of first list</li>
    <li>third list item of first list</li>
  </ul>
  <p>third para</p>
  <ul>
    <li>first list item of second list</li>
  </ul>
  <p>fourth para</p>
  <ul>
    <li>first list item of third list</li>
    <li>second list item of third list</li>
  </ul>
</root>

Regards,
Mukul

--- Ferdinand Soethe <xml-dev@soethe.net> wrote:

> 
> I have an XML-document with paragraphs and list
> items that have no
> wrapper element around each list.
> 
> Something like this:
> 
> <par>my first para</par>
> <par>second para</par>
> <li>first list item of first list</li>
> <li>second list item of first list</li>
> <li>third list item of first list</li>
> <par>third para</par>
> <li>first list item of second list</li>
> <par>fourth para</par>
> <li>first list item of third list</li>
> <li>second list item of third list</li>
> 
> In my transformation I would like to add these
> implicit wrapper
> element around each of the list to get something
> like
> 
> <p>my first para</p>
> <p>second para</p>
> <ul>
> <li>first list item of first list</li>
> <li>second list item of first list</li>
> <li>third list item of first list</li>
> </ul>
> <p>third para</p>
> <ul>
> <li>first list item of second list</li>
> </ul>
> <p>fourth para</p>
> <ul>
> <li>first list item of third list</li>
> <li>second list item of third list</li>
> </ul>
> 
> My attempt to solve this with
> 
> <xsl:template match="Aufzaehlungspunkt">
>     
>   <xsl:if test="not(preceding-sibling::li)">
>     <ul>
>   </xsl:if>
>   
>   <li><xsl:apply-templates/></li>
> 
>   <xsl:if test="not(following-sibling::li)">
>     </ul>
>   </xsl:if>
> 
> </xsl:template>
> 
> ran into two separate problems:
> 
> 1. I'm not allowed to use <ul> without the matching
> </ul> (even though
>    that is in a separate if-branch below.
> 
> 2. The preceding-sibling and following-sibling-axes
> are only true when
>    dealing with the very first and the very last
> <li> in the document.
>    So rather than meaning 'previous element is not
> <li>' the meaning
>    'there is no more previous <li>-element in this
> document'.
> 
> Any ideas how to solve these problems with XML?
> 
> Oh, btw. I saw the solution suggested some years ago
> 
> <officers>
> <xsl:for-each select='/doc/person[@er="officer"]'>
> <person><xsl:value-of select='.'/></person>
> </xsl:for-each>
> </officers>
> 
> <xsl:for-each
> select='/doc/person[not(@er="officer")]'>
> <person><xsl:value-of select='.'/></person>
> </xsl:for-each>
> 
> </perslist>
>  </xsl:template>
> 
>  but this doesn't seem to be an option since I'm not
> using the
>  procedural style of processing my document.
> 
>  Thanks for any input,
> 
>  --
>  Ferdinand
> 
> --
> Ferdinand Soethe


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS