I'm really stuck attempting to pull bulleted text from a rather unwieldy source. Ideally, I'd like to be able maintain the structure of bulleted items as they appeared in an odp slide. I'm using an <xsl:for-each> to loop through the text items. Essentially, I need to figure out how to build a <ul> within a <ul> correctly in my output. Any ideas if this is even possible?

The source looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<office:document-content xmlns:dom="http://www.w3.org/2001/xml-events"
  xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
  xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
  xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
  xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
  xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"
  xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
  xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
  xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0">
  <office:body>
    <office:presentation>
      <draw:page draw:name="Slide1" draw:style-name="a1271"
        draw:master-page-name="Master1-Layout3-cust-Bullet"
        presentation:presentation-page-layout-name="Master1-PPL3">
        <draw:frame draw:id="id109" presentation:style-name="a1039"
                    draw:name="Content Placeholder 1" svg:x="0.31258in" svg:y="1.29095in"
                    svg:width="9.33243in" svg:height="3.8175in" presentation:class="outline"
                    presentation:placeholder="false">
                    <draw:text-box>
                        <text:list text:style-name="a1012">
                            <text:list-item>
                                <text:p text:style-name="a1011" text:class-names=""
                                    text:cond-style-name=""><text:span text:style-name="a1010"
                                        text:class-names="">First Bullet:</text:span></text:p>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1015">
                            <text:list-item>
                                <text:list text:style-name="a1015">
                                    <text:list-item>
                                        <text:p text:style-name="a1014" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1013" text:class-names=""
                                                >Sub-bullet 1: info for sub-bullet
                                            1</text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1018">
                            <text:list-item>
                                <text:list text:style-name="a1018">
                                    <text:list-item>
                                        <text:p text:style-name="a1017" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1016" text:class-names=""
                                                >Sub-bullet 2: info for sub-bullet
                                            2</text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1021">
                            <text:list-item>
                                <text:list text:style-name="a1021">
                                    <text:list-item>
                                        <text:p text:style-name="a1020" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1019" text:class-names=""
                                                >Sub-bullet 3: info for sub-bullet
                                            3</text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1025">
                            <text:list-item>
                                <text:list text:style-name="a1025">
                                    <text:list-item>
                                        <text:p text:style-name="a1024" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1022" text:class-names=""
                                                >Sub-bullet 4: info for sub-bullet
                                                4</text:span><text:span text:style-name="a1023"
                                                text:class-names=""/></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1029">
                            <text:list-item>
                                <text:p text:style-name="a1028" text:class-names=""
                                    text:cond-style-name=""><text:span text:style-name="a1026"
                                        text:class-names="">Second Bullet:</text:span><text:span
                                        text:style-name="a1027" text:class-names=""/></text:p>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1032">
                            <text:list-item>
                                <text:list text:style-name="a1032">
                                    <text:list-item>
                                        <text:p text:style-name="a1031" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1030" text:class-names=""
                                                >Sub-bullet 5: info for sub-bullet
                                            5</text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1035">
                            <text:list-item>
                                <text:list text:style-name="a1035">
                                    <text:list-item>
                                        <text:p text:style-name="a1034" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1033" text:class-names=""
                                                >Sub-bullet 6: info for sub-bullet
                                            6</text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                        <text:list text:style-name="a1038">
                            <text:list-item>
                                <text:list text:style-name="a1038">
                                    <text:list-item>
                                        <text:p text:style-name="a1037" text:class-names=""
                                            text:cond-style-name=""><text:span
                                                text:style-name="a1036" text:class-names=""
                                                ><text:tab/></text:span></text:p>
                                    </text:list-item>
                                </text:list>
                            </text:list-item>
                        </text:list>
                    </draw:text-box>
                    <svg:desc/>
                </draw:frame>
      </draw:page>
    </office:presentation>
  </office:body>
</office:document-content>

My stylesheet looks like:

<xsl:stylesheet
	version="2.0"
	xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
	xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
	xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
	xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
	xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
	xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
	xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
	xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
	xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
	xmlns:math="http://www.w3.org/1998/Math/MathML"
	xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
	xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
	xmlns:dom="http://www.w3.org/2001/xml-events"
	xmlns:xforms="http://www.w3.org/2002/xforms"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
	office:class="text"
	office:version="1.0"
	exclude-result-prefixes="#all">
	<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>


<xsl:template match="/">

<ul>  
<xsl:for-each select="office:document-content/office:body/office:presentation/draw:page/draw:frame/draw:text-box/text:list">    
<xsl:choose>  
  <xsl:when test="text:list-item[not(text:list)][text:p/text:span/text()]">  
     <xsl:variable name="bulletString" select="text:list-item/text:p/text:span"/>  
          <li><xsl:value-of select="$bulletString"/></li>  
   </xsl:when>  
  <xsl:when test=".[not(preceding-sibling::text:list/text:list-item/text:list)]">  
      <ul>  
      <xsl:for-each select=".[following-sibling::text:list/text:list-item/text:list]">       <xsl:variable name="subBulletString" select="text:list-item/text:list/text:list-item/text:p/text:span"/>  
   <li><xsl:value-of select="$subBulletString"/></li>  
    <xsl:for-each select="following-sibling::text:list[text:list-item/text:list]">  
<li><xsl:value-of select="text:list-item/text:list/text:list-item/text:p/text:span"/></li>  
	 </xsl:for-each>    
  </xsl:for-each>  
      </ul>  
 </xsl:when>
</xsl:choose>

</xsl:for-each>  
</ul>

</xsl:template>


</xsl:stylesheet>

Here's the output I'm getting:

<ul>
   <li>First Bullet:</li>
   <ul>
      <li>Sub-bullet 1: info for sub-bullet
                                            1</li>
      <li>Sub-bullet 2: info for sub-bullet
                                            2</li>
      <li>Sub-bullet 3: info for sub-bullet
                                            3</li>
      <li>Sub-bullet 4: info for sub-bullet
                                                4 </li>
      <li>Sub-bullet 5: info for sub-bullet
                                            5</li>
      <li>Sub-bullet 6: info for sub-bullet
                                            6</li>
      <li/>
   </ul>
   <li>Second Bullet: </li>
</ul>

But I need it to look like this (maintaining two separate nested <ul>'s):

<ul>
   <li>First Bullet:</li>
   <ul>
      <li>Sub-bullet 1: info for sub-bullet
                                            1</li>
      <li>Sub-bullet 2: info for sub-bullet
                                            2</li>
      <li>Sub-bullet 3: info for sub-bullet
                                            3</li>
      <li>Sub-bullet 4: info for sub-bullet
                                                4 </li>
   </ul>
   <li>Second Bullet: </li>
       <ul>
         <li>Sub-bullet 5: info for sub-bullet
                                            5</li>
      <li>Sub-bullet 6: info for sub-bullet
                                            6</li>
       </ul>
</ul>

My source may not always have two nested <ul> tags, or any at all, so I need to keep my code flexible. It seems like I really need a do-until loop to accomplish this? Which really makes things difficult in XSLT.

Any help is appreciated.

This article has been dead for over six months. Start a new discussion instead.