gladman
gladman

Reputation: 1266

XSLT format a xml data file to multiple table display using HTML format

I have a xml format data file, it contains information about tests, I want to get a good look view in browser, I want exact these information in different tables, all test info table, every module test info table, and test failed case table.

<testsuites tests="111" failures="3" disabled="0" errors="0" time="60.947" name="AllTests">
  <testsuite name="ChdrvTestAout" tests="4" failures="0" disabled="0" errors="0" time="0">
  </testsuite>
  <testsuite name="ChdrvTestTuner" tests="28" failures="3" disabled="0" errors="0" time="60.944">
    <testcase name="Case0001" status="run" time="0.001" classname="ChdrvTestTuner" />
    <testcase name="Case0007" status="run" time="27.271" classname="ChdrvTestTuner">
      <failure message="Value of: CHDRV_TEST_TUNER_0007()&#x0A;  Actual: 0&#x0A;Expected: (1)&#x0A;Which is: 1" type=""><![CDATA[src/chdrv_tuner_test.cc:71
Value of: CHDRV_TEST_TUNER_0007()
  Actual: 0
Expected: (1)
Which is: 1]]></failure>
    </testcase>
  </testsuite>
  <testsuite name="FactorialTest" tests="3" failures="0" disabled="0" errors="0" time="0">
  </testsuite>
  <testsuite name="IsPrimeTest" tests="3" failures="0" disabled="0" errors="0" time="0">
  </testsuite>
</testsuites>

I want to using XSLT format to HTML, to show data in multiple tables, I want to show this data in seperate module tables, like format:

-------------------------------------
module name  |  tests    |     failures
---------------------------------------
alltests     |   111     |      3
--------------------------------------

-------------------------------------
module name  |  tests    |     failures
---------------------------------------
ChdrvTestAout|   4       |      0
--------------------------------------

-------------------------------------
module name   |  tests    |     failures
---------------------------------------
ChdrvTestTuner|   28      |      3
--------------------------------------

----------------------------------------------------------------------
casename  |   module             |      failed message
----------------------------------------------------------------------
case0007  |   ChdrvTestTuner     | src/chdrv_tuner_test.cc:71
----------------------------------------------------------------------

please see what I have tried here http://www.pastebin.ca/2414163, but it only show the "alltest" table of the first one above? how to write XSLT to do this? highly appreciate your help

Here is the "/" template of the XSLT:

<xsl:template match="/">
  <html>
  <body>
  <h2 align="center">ChangHong driver test report!!!</h2>
  <xsl:apply-templates select="testsuites"/>
  <xsl:apply-templates select="testsuite"/>
  <xsl:apply-templates select="testcase"/>
  <xsl:apply-templates select="failure"/>
  </body>
  </html>
</xsl:template>

many thanks!!!

Upvotes: 0

Views: 1637

Answers (1)

LarsH
LarsH

Reputation: 27994

When this stylesheet is executed, it starts by applying templates to the root node, /. This fires your xsl:template match="/".

While that template is being applied, the context node is /. So when it processes

  <xsl:apply-templates select="testsuites"/>
  <xsl:apply-templates select="testsuite"/>
  <xsl:apply-templates select="testcase"/>
  <xsl:apply-templates select="failure"/>

each of those XPath expressions is evaluated relative to /. So for the first one, you're asking it to apply templates to /testsuites (immediate child[ren] of the root node named testsuites). That's fine, because there is such a node.

But for the second one, you're asking it to apply templates to /testsuite (immediate children of the root node, named testsuite). No such node exists. The same is true for testcase and failure.

It doesn't matter that you have templates that match those other elements, because you are never applying templates to them.

To fix the problem, apply templates using the descendant axis:

  <xsl:apply-templates select="testsuites"/>
  <xsl:apply-templates select="//testsuite"/>
  <xsl:apply-templates select="//testcase"/>
  <xsl:apply-templates select="//failure"/>

By the way, in your match patterns such as

<xsl:template match="//testsuite">

the // doesn't accomplish anything. A match pattern can match any node anywhere in the document; it's as if it's an XPath expression for which the context node is arbitrary. What does matter is that the matched node has been selected by an xsl:apply-templates somewhere else.

Another way to say all that is that the apply-templates select expressions need to be explicit about context, while match patterns do not. So you need to move the // from the match patterns to the apply-templates select expressions.

Upvotes: 1

Related Questions