0
votes

I'm trying to achieve a tree view of an xml file using XSLT and css. I have nested children in xml and I'm iterating through them to display content of each entry.

Each child is a logger with message entries. I would like to have each child table indented according to ancestor count which i get correctly. however trying to set the table margin dynamically margin-left="$margin*10" doesnot work.

This is my XSLT / xml

<xsl:template match="operationLogger">
    <xsl:variable name="margin" select="count(ancestor::*) * 10"/>
      <table class="normalTable" cols="4">
        <xsl:attribute name="margin-left">
          <xsl:value-of select="$margin"/>
        </xsl:attribute>
        <tr class="errorsCollectionTitle">
          <td colspan="4">
            <xsl:value-of select="@name"/>
          </td>
        </tr>
        <xsl:if test="operationLogEntry">
          <xsl:apply-templates select="operationLogEntry"/>
        </xsl:if>
        <xsl:if test="operationLogger">
          <xsl:apply-templates select="operationLogger"/>
        </xsl:if>
      </table>
  </xsl:template>

  <xsl:template match="operationLogEntry">
    <tr>
      <xsl:attribute name="class">
        <xsl:choose>
          <xsl:when test="position() mod 2 = 1">rowData</xsl:when>
          <xsl:otherwise>rowAlternatingData</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <td>
        <xsl:attribute name="class">
          <xsl:choose>
            <xsl:when test="@level = 'Error'">errorImage</xsl:when>
            <xsl:when test="@level = 'Warning'">warningImage</xsl:when>
            <xsl:when test="@level = 'Info'">informationImage</xsl:when>
            <xsl:when test="@level = 'Debug'">informationImage</xsl:when>
          </xsl:choose>
        </xsl:attribute>
      </td>
      <td class="timeStamp">
        <xsl:value-of select="@timeStamp"/>
      </td>
      <td class="source">
        <xsl:value-of select="../loggerSource/@computer" />
        /
        <xsl:value-of select="../loggerSource/@user" />
      </td>
      <td class="message">
          <div>
        <xsl:attribute name="class">
            <xsl:choose>
              <xsl:when test="@level = 'Error'">errorColor</xsl:when>
              <xsl:when test="@level = 'Warning'">warningColor</xsl:when>
              <xsl:when test="@level = 'Info'">informationColor</xsl:when>
              <xsl:when test="@level = 'Debug'">informationColor</xsl:when>
            </xsl:choose>
          </xsl:attribute>
          <xsl:value-of select="@message"/>
        </div>
      </td>
    </tr>
  </xsl:template>
<operationLogger name="">
      <loggerSource domain="user" computer="computer" user="account" />
      <operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Adding 1 to transactions list" />
      <operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Executing 1 transactions..." />
      <operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Executed 1 transactions successfully!" />
      <operationLogger name="TransactionOperationCollection.Execute()">
        <loggerSource domain="user" computer="computer" user="account" />
        <operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Commiting transaction 0:Transaction" />
        <operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Committed transaction 0:Transaction" />
        <operationLogger name="TransactionOperation.Commit()">
        <operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Setting Auditonly" />
          <operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Succesfully changed Audit Only" />
        </operationLogger>
      </operationLogger>
    </operationLogger>

and I tried looping from 1 to 'number of ancestors' and adding span or div. I tried pushing the content of the first row. nothing seems to work for me.

Any help would be greatly appreciated!

1

1 Answers

2
votes

There is no such thing as a margin-left attribute. You can use a style attribute for this, though:

<xsl:attribute name="style">
    <xsl:value-of select="concat('margin-left: ', $margin, 'px;')"/>
</xsl:attribute>

But using inline styles is rarely a good thing. I suggest you place your tables in a ul/li hierarchy. This way, you can put the margins in your CSS file/<style> section rather than calculating them dynamically:

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

<xsl:template match="operationLogger">
  <li>
    <table class="normalTable" cols="4">
      <tr class="errorsCollectionTitle">
        <td colspan="4">
          <xsl:value-of select="@name"/>
        </td>
      </tr>
      <xsl:apply-templates select="operationLogEntry"/>
    </table>
    <xsl:if test="operationLogger">
      <ul>
        <xsl:apply-templates select="operationLogger"/>
      </ul>
    </xsl:if>
  </li>
</xsl:template>