tmaric
tmaric

Reputation: 5477

Is there a Linux command line tool sequence for converting XML files into a single HTML file?

I have a bunch of XML files, and I would like to visualize them as tables in an HTML file. I have searched on the net and found a tutorial on XML->HTML conversion, and a bunch of blogs describing command line tools for HTML/XML/JSON conversion.

Is it possible to use command line tools in Linux to convert a bunch of XML files into a HTML file where each XML file is represented as a table?

Edit: More background information.

I actually want to analyze the XML output of Google Test, that I'm using to develop geometrical algorithms. Here is how the XML looks like for a single test application:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="27" failures="0" disabled="0" errors="0" timestamp="2014-07-18T10:27:10" time="0.002" name="AllTests">
  <testsuite name="lineSegmentIntersection" tests="3" failures="0" disabled="0" errors="0" time="0">
    <testcase name="halfspaceNoIntersection" status="run" time="0" classname="lineSegmentIntersection" />
    <testcase name="halfspacePointIntersection" status="run" time="0" classname="lineSegmentIntersection" />
    <testcase name="halfspaceRegularIntersection" status="run" time="0" classname="lineSegmentIntersection" />
  </testsuite>
  <testsuite name="polygonIntersection" tests="6" failures="0" disabled="0" errors="0" time="0">
    <testcase name="halfspaceNoIntersection" status="run" time="0" classname="polygonIntersection" />
    <testcase name="halfspacePointFullIntersection" status="run" time="0" classname="polygonIntersection" />
    <testcase name="halfspacePointIntersection" status="run" time="0" classname="polygonIntersection" />
    <testcase name="halfspaceEdgeIntersection" status="run" time="0" classname="polygonIntersection" />
    <testcase name="halfspaceDiagonalIntersection" status="run" time="0" classname="polygonIntersection" />
    <testcase name="halfspaceRegularIntersection" status="run" time="0" classname="polygonIntersection" />
  </testsuite>
  <testsuite name="aabboxIntersection" tests="5" failures="0" disabled="0" errors="0" time="0">
    <testcase name="AABBtrueIntersection" status="run" time="0" classname="aabboxIntersection" />
    <testcase name="AABBpointIntersection" status="run" time="0" classname="aabboxIntersection" />
    <testcase name="AABBedgeIntersection" status="run" time="0" classname="aabboxIntersection" />
    <testcase name="AABBfaceIntersection" status="run" time="0" classname="aabboxIntersection" />
    <testcase name="AABBnoIntersection" status="run" time="0" classname="aabboxIntersection" />
  </testsuite>
  <testsuite name="polyhedronIntersection" tests="11" failures="0" disabled="0" errors="0" time="0.002">
    <testcase name="AABBpointIntersection" status="run" time="0.001" classname="polyhedronIntersection" />
    <testcase name="AABBedgeIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="AABBfaceIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="AABBtrueIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="halfspacePointIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="halfspaceEdgeIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="halfspaceFaceEmptyIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="halfspaceFaceFullIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="cubeSpatialDiagonalIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="cubeHalvedIntersection" status="run" time="0" classname="polyhedronIntersection" />
    <testcase name="cubeHalvedDiagonally" status="run" time="0.001" classname="polyhedronIntersection" />
  </testsuite>
  <testsuite name="inside" tests="2" failures="0" disabled="0" errors="0" time="0">
    <testcase name="halfspaceTriangle" status="run" time="0" classname="inside" />
    <testcase name="halfspaceTetrahedron" status="run" time="0" classname="inside" />
  </testsuite>
</testsuites>

I have dozens of test applications implemented for different geometrical operations, and they all produce such an XML file. As the number of tests grows, I am loosing an overview since I am compiling (generic C++ code) and executing all of them each time I implement a change in the source code that deals with geometry. That's why I would like to pick all of them up and visualize them somehow in tabular form.

Google Test does produce a nice colored output to the command line, but for dozens of applicatins and each of them containing ~10 tests, I need to scroll up to see what has failed.

Upvotes: 0

Views: 3159

Answers (3)

Tombart
Tombart

Reputation: 32436

Using xq you could convert the document to JSON, which might have better tooling available:

convert to JSON, extract testsuite:

xq test.xml -j | jq '.testsuites.testsuite[]'

jq then supports converting to CSV or TSV

$ xq test.xml -j | \
  jq '.testsuites.testsuite[] | [ ."@name", ."@tests", ."@time", ."@failures", ."@errors" ] | @csv'
"lineSegmentIntersection\t3\t0\t0\t0"
"polygonIntersection\t6\t0\t0\t0"
"aabboxIntersection\t5\t0\t0\t0"
"polyhedronIntersection\t11\t0.002\t0\t0"
"inside\t2\t0\t0\t0

HTML output is a bit trickier:

$ xq test.xml -j | \
  jq -r '.testsuites.testsuite | map("<tr><td>" + ."@name" + "</td><td>" + (."@time") + "</td></tr>") | ["<table>"] + . + ["</table>"] | .[]'
<table>
<tr><td>lineSegmentIntersection</td><td>0</td></tr>
<tr><td>polygonIntersection</td><td>0</td></tr>
<tr><td>aabboxIntersection</td><td>0</td></tr>
<tr><td>polyhedronIntersection</td><td>0.002</td></tr>
<tr><td>inside</td><td>0</td></tr>
</table>

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163488

As well as XSLT to do the transformation, you might like to look at David Lee's xmlsh which is a shell-like tool for defining XML processing pipelines (there's also XProc and Ant which are widely used for this purpose, but I suggest xmlsh since you appear to be a shell fan).

The XSLT transformation for this input might look something like this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
   <head>...</head>
   <body><xsl:apply-templates/></body>
  </html>
</xsl:template>

<xsl:template match="testsuites">
  <table>
    <thead>
      <tr><th>name</th><th>.....</th>
    </thead>
    <tbody>
      <xsl:apply-templates/>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="testcase">
  <tr>
   <td><xsl:value-of select="@name"/>
   <td><xsl:value-of select="@status"/>
   <td><xsl:value-of select="@time"/>
   <td><xsl:value-of select="@classname"/>
  </tr>
</xsl:template>

</xsl:stylesheet>

There are many XSLT processors you can use from the command line. If you choose Saxon, the command would be

java -jar saxon9.jar -s:source.xml -xsl:stylesheet.xsl -o:output.html

Upvotes: 1

XML is more a family of formats -since it is a markup language- (e.g. XHTML, Docbook, ...) than a particular format. You need to know precisely which XML schema is obeyed by your XML files.

You probably want some XSLT processor (or perhaps Xquery). See also SAX parsers and Expat

Upvotes: 1

Related Questions