0

I'm doing html to xml transformation. In html I have table like this,

<doc>
<ol>
    <li>
        <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
        <ol>
            <li>nested list1</li>
            <li>nested <span style="color: rgb(255,0,255);">The scope of this project is to:</span> list1</li>
            <li>nested list1</li>
            <li>nested list1</li>
            <li>nested list1</li>
        </ol>
    </li>
    <li>
        <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
    </li>
    <li>
        <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
    </li>
</ol>

Here I need to transform html elements names to certain xml elements name and should cover the text content by <para> element.

SO my output should be,

<doc>
    <oli>
        <listitem><para>List<style type="color: rgb(255,0,255);">The scope of this project is to:</style></para>
            <oli>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested <style type="color: rgb(255,0,255);">The scope of this project is to:</style> list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
            </oli>
        </listitem>
        <listitem><para>
            List<style type="color: rgb(255,0,255);">The scope of this project is to:</style>
        </para></listitem>
        <listitem><para>
            List<style type="color: rgb(255,0,255);">The scope of this project is to:</style>
        </para></listitem>
    </oli>
</doc>

I have written following xsl to transform html to xml,

<xsl:template match="ol">
        <oli>
            <xsl:apply-templates/>           
        </oli>
    </xsl:template>

    <xsl:template match="li">
        <listitem>
            <para>
                <xsl:apply-templates/>
            </para>
        </listitem>
    </xsl:template>

    <xsl:template match="span">
        <style type="{@style}">
            <xsl:apply-templates/>
        </style>
    </xsl:template>

    <xsl:template match="p">
        <para>
            <xsl:apply-templates/>
        </para>
    </xsl:template>

    <xsl:template match="li/p">
        <xsl:apply-templates/>
    </xsl:template>

The problem I have is when ul contain nested list, li text that has contain nested list is not correctly covered with <para> element.

in above example currunt output that I'm getting for nested list is follwos,

<listitem><para>
            List<style type="color: rgb(255,0,255);">The scope of this project is to:</style>
            <oli>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested <style type="color: rgb(255,0,255);">The scope of this project is to:</style> list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
                <listitem><para>nested list1</para></listitem>
            </oli>
        </para></listitem>

so simply, instead of

<listitem><para>
                List<style type="color: rgb(255,0,255);">The scope of this project is to:</style>
                <oli>
              ........
                </oli>
             </para>
 </listitem>

I need,

    <listitem><para>
           List<style type="color: rgb(255,0,255);">The scope of this project is to:</style>
           </para>
                    <oli>
                  ........
                    </oli>

     </listitem>

I tried to cover text() content of li element by <para> but then <span> elements are not coming to the output.

Can anyone suggest a method how can I do this..

1 Answer 1

1

I would simply change the template:

<xsl:template match="li/p">
    <xsl:apply-templates/>
</xsl:template>

to:

<xsl:template match="li[p]">
   <listitem>
     <xsl:apply-templates/>
   </listitem>
</xsl:template>

This template will match an <li> that contains a <p>. In this case, you don't have to add some <para>. For the <li>s that contain some <p>, the other template will match, and it does output the desired <para>.

Alternatively, you can also do something like this:

  • discard the template <xsl:template match="li/p">
  • modify the template <xsl:template match="li"> like follows:

    <xsl:template match="li">
      <xsl:choose>
        <xsl:when test="p">
          <listitem>
            <xsl:apply-templates/>
          </listitem>
        </xsl:when>
        <xsl:otherwise>
          <listitem>
            <para>
              <xsl:apply-templates/>
            </para>
          </listitem>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.