tags:

views:

524

answers:

3

Please review my code and give me your advise on this:

XML file: content.xml:

<content>
<page id="page-1">
<!-- ... -->
<block-center>
  <block-center-row id="block-center-row-1">
    <cd>
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
    </cd>
    <cd>
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
    </cd>
  </block-center-row>
  <block-center-row id="block-center-row-2">
    <block-center-colunm id="block-center-2-1">
      <book>
        <title>Book Title1</title>
        <author>Book Author1</author>
      </book>
      <book>
        <title>Book Title2</title>
        <author>Book Author2</author>
      </book>
      <book>
        <title>Book Title3</title>
        <author>Book Author3</author>
      </book>
    </block-center-colunm>
    <block-center-colunm id="block-center-2-2">
      <seminar>
        <author>Seminar author1</author>
        <durable>3</durable>
      </seminar>
      <seminar>
        <author>Seminar author2</author>
        <durable>1.5</durable>
      </seminar>
      <seminar>
        <author>Seminar author3</author>
        <durable>2</durable>
      </seminar>
      <seminar>
        <author>Seminar author4</author>
        <durable>3</durable>
      </seminar>
    </block-center-colunm>
  </block-center-row>
</block-center>
</page>
<!-- ... -->
</content>

XSL file: block-center-1-1.xsl:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:template name="block-center-row-1">
    <div class="block-center-row">
      <h2>My CD Collection</h2>
      <table border="1" width="100%">
        <tr bgcolor="#9acd32">
          <th>Title</th>
          <th>Artist</th>
        </tr>
        <xsl:for-each select="
          content/page[@id=$pageId]/block-center/
          block-center-row[@id='block-center-row-1']/cd
        ">
          <tr>
            <td>
              <xsl:value-of select="title" />
            </td>
            <xsl:choose>
              <xsl:when test="price &gt; 10">
                <td bgcolor="#ff00ff">
                  <xsl:value-of select="artist" />
                </td>
              </xsl:when>
              <xsl:when test="price &gt; 9">
                <td bgcolor="#cccccc">
                  <xsl:value-of select="artist" />
                </td>
              </xsl:when>
              <xsl:otherwise>
                <td>
                  <xsl:value-of select="artist" />
                </td>
              </xsl:otherwise>
            </xsl:choose>
          </tr>
        </xsl:for-each>
      </table>
    </div>
  </xsl:template>
</xsl:stylesheet>

XSL file block-center.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:import href="block-center-1-1.xsl" />
  <xsl:template name="block-center">
    <!-- if put here. It work properly -->
    <div class="block-center"> 
      <xsl:for-each select="content/page[@id=$pageId]/block-center/block-center-row">
        <xsl:choose>
          <!-- // I does not work here --> 
          <xsl:when test="@id='block-center-row-1'">
            <xsl:call-template name="block-center-row-1" />
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
    </div>
  </xsl:template>
</xsl:stylesheet>

I dont know why It does not work (not out put data) if I call <xsl:call-template> inside <xsl:for-each> loop. Otherwise, It's OK.

+1  A: 

I have a few remarks to make. First off, it is a bad idea to make format implications in the XML. Having elements that are called <block-center> or <block-center-colunm> is not only unnecessarily verbose, it will also make your head hurt as soon as their contents is not going to be displayed in a block in the center anymore.

Second, let go of <xsl:call-template> and <xsl:for-each>. They may seem convenient if you have procedural programming background, but they are the wrong choice. Use <xsl:apply-templates> instead, it leads to code that's cleaner and easier to understand.

Now to your XSL. Your second XSL (block-center.xsl) - what does it do? Why do you have two separate XSL files? Also, it is missing a variable or parameter declaration. I've used:

<xsl:variable name="pageId" select="'page-1'" />

for my tests. It also has only one template (<xsl:template name="block-center">) that is never actually being called, so it did not do anything for me. I've added

<xsl:template match="/">
  <xsl:call-template name="block-center" />
</xsl:template>

so it would at least do anything.

Your other XSL file (block-center-1-1.xsl) has a for-each loop that is not looking at the right context. You already are in the following context when you enter the template "block-center-row-1":

content/page[@id=$pageId]/block-center/block-center-row

so all you need to do in the for-each loop is:

<xsl:for-each select="cd">

and it will start to output all <cd> nodes.

Tomalak
You've beaten me to it. :-) I was still writing my answer when you posted yours...
Workshop Alex
A: 

Maybe change:

<xsl:for-each select="content/page[@id=$PageId]/block-center/block-center-row">

into

<xsl:for-each select="/content/page[@id=$PageId]/block-center/block-center-row">

I guess it can't find the content node since it's calling the template from within another node.

Workshop Alex
A: 

Many thanks for your euthusiasm! It's now works properly if I change in block-center-1-1.xsl file TO

OR