I have a problem. I made a table in a xslt stylesheet. Now I don't know how to put only one Unit-node in the upper table and then all the funktion nodes under that. For the second, third... Unit-node I want both tables under that.
example in a picture in my dropbox (I have not enough point on stckoverflow)
https://www.dropbox.com/s/jfzii4ytllfb6m9/Mappe1.pdf?dl=0
<?xml version="1.0" encoding="UTF-8"?>
<PLC_LOG>
<HostName>DERTLP0350</HostName>
<Unit>
<Line>123456</Line>
<Funktion>
<sName>CounterDown1</sName>
<sDescription>automatic</sDescription>
<tMaxExecutionTime>T#3s</tMaxExecutionTime>
<Timestamp>2014-12-15-14:11:10.298</Timestamp>
<Line>12345678</Line>
<bFinish>TRUE</bFinish>
<bResult>TRUE</bResult>
</Funktion><sName>CounterDown</sName>
<sDescription>Test of the CounterDown</sDescription>
<tMaxExecutionTime>T#15s</tMaxExecutionTime>
<bFinish>TRUE</bFinish>
<bResult>FALSE</bResult>
<Timestamp>2014-12-15-14:11:11.179</Timestamp>
</Unit>
<Unit>
<Line>123456</Line>
<Funktion>
<sName>CounterDown1</sName>
<sDescription>automatic</sDescription>
<tMaxExecutionTime>T#3s</tMaxExecutionTime>
<Timestamp>2014-12-15-14:11:10.298</Timestamp>
<Line>12345678</Line>
<bFinish>TRUE</bFinish>
<bResult>FALSE</bResult>
</Funktion><sName>CounterDown</sName>
<sDescription>Test of the CounterDown</sDescription>
<tMaxExecutionTime>T#15s</tMaxExecutionTime>
<bFinish>TRUE</bFinish>
<bResult>FALSE</bResult>
<Timestamp>2014-12-15-14:11:11.179</Timestamp>
</Unit>
</PLC_LOG>
My made my table with this code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<head>
<title>Automated Test of the System</title>
<style type="text/css">
h1 {color: #000000}
h2 {color: #000000}
</style>
</head>
<body bgcolor="white">
<h1 >
<a name="Content">Testreport PLC</a>
</h1>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="PLC_LOG">
<table border="1">
<thead>
<tr bgcolor="#BDBDBD">
<th width="650" align="center">HostName</th>
<th width="650" align="center">Link to Configuration</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="/PLC_LOG">
<tr>
<td align="center">
<xsl:value-of select="HostName"/>
</td>
<td align="center">
<xsl:value-of select="HostName"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
<table border="1">
<thead>
<tr bgcolor="#0070C0">
<th colspan="7">TestUNIT</th>
</tr>
<tr bgcolor="#0070C0">
<th width="200" align="center">Name</th>
<th width="325" align="center">Description</th>
<th width="325" align="center">Message</th>
<th width="100" align="center">MaxExecutionTime</th>
<th width="150" align="center">Timestamp</th>
<th width="100" align="center">TestFinish</th>
<th width="100" align="center">Result</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="/*/Unit">
<tr>
<td>
<xsl:value-of select="sName"/>
</td>
<td>
<xsl:value-of select="sDescription"/>
</td>
<td>
<xsl:for-each select="node()[starts-with(name(), 'Line')]">
<xsl:value-of select="."/>
</xsl:for-each>
</td>
<td align="center">
<xsl:value-of select="tMaxExecutionTime"/>
</td>
<td>
<xsl:value-of select="Timestamp"/>
</td>
<xsl:choose>
<xsl:when test="bFinish='TURE'">
<td bgcolor="#00FF00" align="center">
<b>Passed</b>
</td>
</xsl:when>
<xsl:when test="bFinish='TRUE'">
<td bgcolor="red" align="center">
<b>Failed</b>
</td>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="bResult='TRUE'">
<td bgcolor="#00FF00" align="center">
<b>Passed</b>
</td>
</xsl:when>
<xsl:when test="bResult='FALSE'">
<td bgcolor="red" align="center">
<b>Failed</b>
</td>
</xsl:when>
</xsl:choose>
</tr>
</xsl:for-each>
</tbody>
</table>
<table border="1">
<thead>
<tr bgcolor="#0099ff">
<th colspan="7">TestFunktion</th>
</tr>
<tr bgcolor="#0099ff">
<th width="200" align="center">Name</th>
<th width="325" align="center">Description</th>
<th width="325" align="center">Message</th>
<th width="100" align="center">MaxExecutionTime</th>
<th width="150" align="center">Timestamp</th>
<th width="100" align="center">TestFinish</th>
<th width="100" align="center">Result</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="/*/*/Funktion">
<tr>
<td>
<xsl:value-of select="sName"/>
</td>
<td>
<xsl:value-of select="sDescription"/>
</td>
<td>
<xsl:for-each select="node()[starts-with(name(), 'Line')]">
<xsl:value-of select="."/>
</xsl:for-each>
</td>
<td align="center">
<xsl:value-of select="tMaxExecutionTime"/>
</td>
<td>
<xsl:value-of select="Timestamp"/>
</td>
<xsl:choose>
<xsl:when test="bFinish='TRUE'">
<td bgcolor="#00FF00" align="center">
<b>Passed</b>
</td>
</xsl:when>
<xsl:when test="bFinish='FALSE'">
<td bgcolor="red" align="center">
<b>Failed</b>
</td>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="bResult='TRUE'">
<td bgcolor="#00FF00" align="center">
<b>Passed</b>
</td>
</xsl:when>
<xsl:when test="bResult='FALSE'">
<td bgcolor="red" align="center">
<b>Failed</b>
</td>
</xsl:when>
</xsl:choose>
</tr>
</xsl:for-each>
</tbody>
</table>
<br></br>
<br></br>
</xsl:template>
</xsl:stylesheet>
Thanks for help!!!!
This is very confusing, esp. since the picture does not seem to match the example input. I would suggest you concentrate first on getting the structure right. Try the following as your starting point:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="PLC_LOG/Unit"/>
</body>
</html>
</xsl:template>
<xsl:template match="Unit">
<table border="1">
<thead>
<tr>
<th colspan="7">TestUNIT</th>
</tr>
<tr>
<th>Name</th>
<th>Description</th>
<th>Message</th>
<th>MaxExecutionTime</th>
<th>Timestamp</th>
<th>TestFinish</th>
<th>Result</th>
</tr>
<tr>
<td><xsl:value-of select="sName"/></td>
<td><xsl:value-of select="sDescription"/></td>
<td><xsl:value-of select="Line"/></td>
<td><xsl:value-of select="tMaxExecutionTime"/></td>
<td><xsl:value-of select="Timestamp"/></td>
<td><xsl:value-of select="bFinish"/></td>
<td><xsl:value-of select="bResult"/></td>
</tr>
</thead>
<tbody>
<tr>
<th colspan="7">TestFunktion</th>
</tr>
<tr>
<xsl:for-each select="Funktion[1]/*">
<th><xsl:value-of select="local-name()"/></th>
</xsl:for-each>
</tr>
<xsl:apply-templates select="Funktion"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="Funktion">
<tr>
<xsl:for-each select="*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>
Once you have the table structure and contents the way you want them, add CSS styling as necessary.
Related
source document:
the below is the xml document.
<?xml version="1.0"?>
<Library>
<Book code="123">
<BookName>XML</BookName>
<Category>Programming</Category>
<Quantity>10</Quantity>
<Price>100</Price>
</Book>
<Book code="345">
<BookName>Photoshop</BookName>
<Category>Design</Category>
<Quantity>50</Quantity>
<Price>200</Price>
</Book>
<Book code="123">
<BookName>XML</BookName>
<Category>Programming</Category>
<Quantity>5</Quantity>
<Price>100</Price>
</Book>
<Book code="345">
<BookName>Photoshop</BookName>
<Category>Design</Category>
<Quantity>10</Quantity>
<Price>200</Price>
</Book>
<Book code="456">
<BookName>Illustrator</BookName>
<Category>Design</Category>
<Quantity>100</Quantity>
<Price>300</Price>
</Book>
</Library>
xslt stylesheet:
this is the present stylesheet. I have tried to use xslt 2. However, I am not getting how to get the desired output.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1>Books Information</h1>
<table border="1">
<xsl:for-each-group select="Library/Book" group-by="Category">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td colspan="4">Category:
<b>
<xsl:value-of select="current-grouping-key()"/>
</b>
</td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<xsl:apply-templates select="current-group()">
<xsl:sort select="#code"/>
</xsl:apply-templates>
</xsl:for-each-group>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Book">
<tr>
<td><xsl:value-of select="#code"/></td>
<td><xsl:value-of select="Quantity"/></td>
<td><xsl:value-of select="Price"/></td>
<td> </td>
</tr>
</xsl:template>
</xsl:stylesheet>
current output
<html>
<body>
<h1>Books Information</h1>
<table border="1">
<tr>
<td colspan="4">Category:
<b>Design</b></td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<tr>
<td>345</td>
<td>50</td>
<td>200</td>
<td></td>
</tr>
<tr>
<td>345</td>
<td>10</td>
<td>200</td>
<td></td>
</tr>
<tr>
<td>456</td>
<td>100</td>
<td>300</td>
<td></td>
</tr>
<tr>
<td colspan="4">Category:
<b>Programming</b></td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<tr>
<td>123</td>
<td>10</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>123</td>
<td>5</td>
<td>100</td>
<td></td>
</tr>
</table>
</body>
</html>
expected output
<html>
<body>
<h1>Books Information</h1>
<table border="1">
<tr>
<td colspan="4">Category:
<b>Design</b></td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<tr>
<td>345</td>
<td>60</td>
<td>200</td>
<td>1200</td>
</tr>
<tr>
<td>456</td>
<td>100</td>
<td>300</td>
<td></td>
</tr>
<tr>
<td colspan="4">Subtotal: 1500</td>
</tr>
<tr>
<td colspan="4">Category:
<b>Programming</b></td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<tr>
<td>123</td>
<td>15</td>
<td>1500</td>
<td></td>
</tr>
<tr>
<td colspan="4">subtotal: 1500</td>
</tr>
<tr>
<td colspan="4">Grand TOtal: 3000</td>
</tr>
</table>
</body>
</html>
It looks like you are doing two lots of grouping here. First by "Category" and within each category you then group by "Code".
You first grouping looks fine, but for the second grouping, you need to replace these lines...
<xsl:apply-templates select="current-group()">
<xsl:sort select="#code"/>
</xsl:apply-templates>
With these lines, as this will then group the books within the current category by their code
<xsl:for-each-group select="current-group()" group-by="#code">
<xsl:sort select="current-grouping-key()" />
<xsl:apply-templates select="." />
</xsl:for-each-group>
In terms of getting the totals for each group, you can use this expression
<xsl:value-of select="sum(current-group()/(Quantity * Price))" />
This will work for both groups, so can be used to get the amount for the "code" and the sub-total for the "category". For the overall total, it would just be this
<xsl:value-of select="sum(Library/Book/(Quantity * Price))" />
Try this XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1>Books Information</h1>
<table border="1">
<xsl:for-each-group select="Library/Book" group-by="Category">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td colspan="4">Category:
<b>
<xsl:value-of select="current-grouping-key()"/>
</b>
</td>
</tr>
<tr>
<th>Book Code</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Price</th>
</tr>
<xsl:for-each-group select="current-group()" group-by="#code">
<xsl:sort select="current-grouping-key()" />
<xsl:apply-templates select="." />
</xsl:for-each-group>
<tr>
<td colspan="4">subtotal: <xsl:value-of select="sum(current-group()/(Quantity * Price))" /></td>
</tr>
</xsl:for-each-group>
<tr>
<td colspan="4">Total: <xsl:value-of select="sum(Library/Book/(Quantity * Price))" /></td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Book">
<tr>
<td><xsl:value-of select="#code"/></td>
<td><xsl:value-of select="Quantity"/></td>
<td><xsl:value-of select="Price"/></td>
<td><xsl:value-of select="sum(current-group()/(Quantity * Price))" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
i've the below xml document.
<toc-div>
<toc-item>
<toc-title>CHAPTER 1 INTRODUCTION</toc-title>
<toc-subitem num="1.">
<toc-title>The British Virgin Islands</toc-title>
<toc-pg>1.001</toc-pg>
</toc-subitem>
<toc-subitem num="2.">
<toc-title>History and early constitutional developments</toc-title>
<toc-pg>1.003</toc-pg>
</toc-subitem>
<toc-subitem num="3.">
<toc-title>Development as a financial centre</toc-title>
<toc-pg>1.008</toc-pg>
</toc-subitem>
<toc-subitem num="4.">
<toc-title>Common Law and Equity</toc-title>
<toc-pg>1.015</toc-pg>
</toc-subitem>
<toc-subitem num="5.">
<toc-title>Statutes</toc-title>
<toc-pg>1.017</toc-pg>
</toc-subitem>
<toc-subitem num="6.">
<toc-title>Taxation</toc-title>
<toc-pg>1.022</toc-pg>
</toc-subitem>
</toc-item>
and i'm applying the below xslt.
<xsl:template match="toc-subitem">
<table>
<td>
<xsl:value-of select="preceding-sibling::toc-title[1]"/>
</td></table>
<xsl:variable name="tocpg">
<xsl:value-of select="current()/toc-pg"/></xsl:variable>
<xsl:variable name="abc">
<xsl:choose>
<xsl:when test="not(contains(#num, '('))">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="before">
<xsl:value-of select="normalize-space(substring-before($tocpg, '.'))"/>
</xsl:variable>
<xsl:variable name="after">
<xsl:value-of select="normalize-space(substring-after($tocpg, '.'))"/>
</xsl:variable>
<xsl:variable name="z">
<xsl:value-of select="current()/#num"/>
</xsl:variable>
<xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')"/>
<xsl:variable name="numa" select="number(translate(#num, '.', ''))" />
<xsl:variable name="itemlevel">
<xsl:value-of select="$ThisDocument//ntw:nums[#num=$abc]/#word"/>
</xsl:variable>
<xsl:variable name="tocitemlevel">
<xsl:value-of select="concat('toc-item-', $itemlevel,'-level')"/>
</xsl:variable>
<xsl:variable name="conc">
<xsl:value-of select="concat('er:#BVI_CH_0',$before, '/P', normalize-space($tocpgtag))"/>
</xsl:variable>
<table class="{$tocitemlevel}">
<tbody>
<tr>
<td class="toc-subitem-num">
<xsl:value-of select="$z" />
</td>
<td class="toc-title">
<xsl:value-of select="current()/toc-title" />
</td>
<td class="toc-pg">
<a href="{$conc}">
<xsl:value-of select="current()/toc-pg" />
</a>
</td>
</tr>
</tbody>
</table>
</xsl:template>
when i'm applying this template, the output i'm getting is as below.
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">1.</td>
<td class="toc-title">The British Virgin Islands</td>
<td class="toc-pg">1.001</td>
</tr>
</tbody>
</table>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">2.</td>
<td class="toc-title">History and early constitutional developments</td>
<td class="toc-pg">1.003</td>
</tr>
</tbody>
</table>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">3.</td>
<td class="toc-title">Development as a financial centre</td>
<td class="toc-pg">1.008</td>
</tr>
</tbody>
</table>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">4.</td>
<td class="toc-title">Common Law and Equity</td>
<td class="toc-pg">1.015</td>
</tr>
</tbody>
</table>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">5.</td>
<td class="toc-title">Statutes</td>
<td class="toc-pg">1.017</td>
</tr>
</tbody>
</table>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">6.</td>
<td class="toc-title">Taxation</td>
<td class="toc-pg">1.022</td>
</tr>
</tbody>
</table>
but i want to get it as below
<table>
<td>CHAPTER 1 INTRODUCTION</td>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">1.</td>
<td class="toc-title">The British Virgin Islands</td>
<td class="toc-pg">1.001</td>
</tr>
</tbody>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">2.</td>
<td class="toc-title">History and early constitutional developments</td>
<td class="toc-pg">1.003</td>
</tr>
</tbody>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">3.</td>
<td class="toc-title">Development as a financial centre</td>
<td class="toc-pg">1.008</td>
</tr>
</tbody>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">4.</td>
<td class="toc-title">Common Law and Equity</td>
<td class="toc-pg">1.015</td>
</tr>
</tbody>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">5.</td>
<td class="toc-title">Statutes</td>
<td class="toc-pg">1.017</td>
</tr>
</tbody>
</table>
<table class="toc-item--level">
<tbody>
<tr>
<td class="toc-subitem-num">6.</td>
<td class="toc-title">Taxation</td>
<td class="toc-pg">1.022</td>
</tr>
</tbody>
</table>
please let me know where I'm going wrong.
Thanks
Note:
Your title table is not valid - it does not have <tr>.
The reason your XSLT gave you duplicate toc-title was that you printed it for every toc-subitem processed. In the solution below it is printed only once.
Make the following change to your XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="//toc-item">
<table>
<td>
<!-- Print the title *once* -->
<xsl:value-of select="./toc-title"/>
</td>
</table>
<!-- Process each subitem -->
<xsl:apply-templates select="toc-subitem"/>
</xsl:template>
<xsl:template match="toc-subitem">
<!-- Removed the <table> with the preceding sibling -->
<xsl:variable name="tocpg">
<xsl:value-of select="current()/toc-pg"/></xsl:variable>
<!-- Put the rest of your XSLT here, no changes there -->
</xsl:template>
</xsl:stylesheet>
You should use separate templates for this (I also cleaned up a bunch of the <xsl:variable>s):
<xsl:template match="toc-title">
<table>
<tr>
<td>
<xsl:value-of select="preceding-sibling::toc-title[1]"/>
</td>
</tr>
</table>
</xsl:template>
<xsl:template match="toc-subitem">
<xsl:variable name="tocpg" select="toc-pg" />
<xsl:variable name="abc" select="1 + contains(#num, '(')" />
<xsl:variable name="before"
select="normalize-space(substring-before($tocpg, '.'))"/>
<xsl:variable name="after"
select="normalize-space(substring-after($tocpg, '.'))"/>
<xsl:variable name="z" select="#num"/>
<xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')"/>
<xsl:variable name="numa" select="number(translate(#num, '.', ''))" />
<xsl:variable name="itemlevel"
select="$ThisDocument//ntw:nums[#num=$abc]/#word"/>
<xsl:variable name="tocitemlevel"
select="concat('toc-item-', $itemlevel,'-level')"/>
<xsl:variable name="conc"
select="concat('er:#BVI_CH_0',$before, '/P',
normalize-space($tocpgtag))"/>
<table class="{$tocitemlevel}">
<tbody>
<tr>
<td class="toc-subitem-num">
<xsl:value-of select="$z" />
</td>
<td class="toc-title">
<xsl:value-of select="toc-title" />
</td>
<td class="toc-pg">
<a href="{$conc}">
<xsl:value-of select="toc-pg" />
</a>
</td>
</tr>
</tbody>
</table>
</xsl:template>
However, I think putting every row in its own table is not a very good design. Why have you chosen to do that?
I don't really understand why you'd want output like that (<td> is not a valid child of <table>, for example, in HTML), but this stylesheet should get you closer (I rewrote the stylesheet to split your code into separate <xsl:template> elements):
Stylesheet
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<table>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="toc-item/toc-title">
<td><xsl:value-of select="."/></td>
</xsl:template>
<xsl:template match="toc-subitem">
<!--
I don't know how your code that fetches the TOC item level is supposed
to work so you'll have to figure that out yourself.
-->
<table class="toc-item-$level-level">
<tbody>
<tr>
<xsl:apply-templates select="#* | node()"/>
</tr>
</tbody>
</table>
</xsl:template>
<xsl:template match="#num">
<td class="toc-subitem-num">
<xsl:value-of select="."/>
</td>
</xsl:template>
<xsl:template match="toc-subitem/toc-title">
<td class="toc-title">
<xsl:value-of select="."/>
</td>
</xsl:template>
<xsl:template match="toc-pg">
<td class="toc-pg">
<a href="{concat('er:#BVI_CH_0', substring-before(., '.'), '/P', translate(., '.', '-'))}">
<xsl:value-of select="."/>
</a>
</td>
</xsl:template>
</xsl:stylesheet>
Input
<?xml version="1.0"?>
<toc-div>
<toc-item>
<toc-title>CHAPTER 1 INTRODUCTION</toc-title>
<toc-subitem num="1.">
<toc-title>The British Virgin Islands</toc-title>
<toc-pg>1.001</toc-pg>
</toc-subitem>
<toc-subitem num="2.">
<toc-title>History and early constitutional developments</toc-title>
<toc-pg>1.003</toc-pg>
</toc-subitem>
<toc-subitem num="3.">
<toc-title>Development as a financial centre</toc-title>
<toc-pg>1.008</toc-pg>
</toc-subitem>
<toc-subitem num="4.">
<toc-title>Common Law and Equity</toc-title>
<toc-pg>1.015</toc-pg>
</toc-subitem>
<toc-subitem num="5.">
<toc-title>Statutes</toc-title>
<toc-pg>1.017</toc-pg>
</toc-subitem>
<toc-subitem num="6.">
<toc-title>Taxation</toc-title>
<toc-pg>1.022</toc-pg>
</toc-subitem>
</toc-item>
</toc-div>
Output
<html>
<body>
<table>
<td>CHAPTER 1 INTRODUCTION</td>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">1.</td>
<td class="toc-title">The British Virgin Islands</td>
<td class="toc-pg">
1.001
</td>
</tr>
</tbody>
</table>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">2.</td>
<td class="toc-title">History and early constitutional developments</td>
<td class="toc-pg">
1.003
</td>
</tr>
</tbody>
</table>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">3.</td>
<td class="toc-title">Development as a financial centre</td>
<td class="toc-pg">
1.008
</td>
</tr>
</tbody>
</table>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">4.</td>
<td class="toc-title">Common Law and Equity</td>
<td class="toc-pg">
1.015
</td>
</tr>
</tbody>
</table>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">5.</td>
<td class="toc-title">Statutes</td>
<td class="toc-pg">
1.017
</td>
</tr>
</tbody>
</table>
<table class="toc-item-$level-level">
<tbody>
<tr>
<td class="toc-subitem-num">6.</td>
<td class="toc-title">Taxation</td>
<td class="toc-pg">
1.022
</td>
</tr>
</tbody>
</table>
</table>
</body>
</html>
Just remove the <html> and <body> elements from the first <xsl:template> rule if you really don't need them.
I have the following XML:
<record>
<fruit>Apples</fruit>
<fruit>Oranges</fruit>
<fruit>Bananas</fruit>
<fruit>Plums</fruit>
<vegetable>Carrots</vegetable>
<vegetable>Peas</vegetable>
<candy>Snickers</candy>
</record>
and the following XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="4.0" encoding="iso-8859-1" indent="yes" />
<xsl:key name="nodes-by-name" match="*" use="name()"/>
<xsl:template match="*">
<table class="fieldGrid" border="0">
<xsl:for-each select="*">
<xsl:if test="not(*)">
<xsl:if test=".!=''''">
<xsl:call-template name="lowestLevel"/>
</xsl:if>
<xsl:if test=".=''''">
<xsl:call-template name="hasChildren"/>
</xsl:if>
</xsl:if>
<xsl:if test="*">
<xsl:call-template name="hasChildren"/>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="lowestLevel">
<tr class="fields">
<td class="fieldName">
<xsl:value-of select="translate(local-name(), ''_'', '' '')" />
</td>
<td class="fieldValue">
<xsl:value-of select="translate(., ''_'', '' '')" />
</td>
</tr>
</xsl:template>
<xsl:template name="hasChildren">
<tr>
<td colspan="2" class="sectionTitle">
<xsl:value-of select="translate(local-name(), ''_'', '' '')" /> <xsl:value-of select="count(key(''nodes-by-name'', name()))" />
</td>
</tr>
<tr>
<td>
<xsl:for-each select="*">
<xsl:if test="not(*)">
<xsl:call-template name="lowestLevel"/>
</xsl:if>
<xsl:if test="*">
<xsl:call-template name="hasChildren"/>
</xsl:if>
</xsl:for-each>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
The problem that I'm having is I get the following output where the number is the sum of the nodes with the same name, not the occurance of this node verses the other nodes with the same name. (I have simplified the html to remove the classes):
<table class="fieldGrid" border="0">
<tr>
<td>fruit 4</td>
<td>Apples</td>
</tr>
<tr>
<td>fruit 4</td>
<td>Oranges</td>
</tr>
<tr>
<td>fruit 4</td>
<td>Bananas</td>
</tr>
<tr>
<td>fruit 4</td>
<td>Plums</td>
</tr>
<tr>
<td>vegetable 2</td>
<td>Carrots</td>
</tr>
<tr>
<td>vegetable 2</td>
<td>Peas</td>
</tr>
<tr>
<td>candy 1</td>
<td>Snickers</td>
<tr>
</table>
I can't seem to figure out how to get the right selector to set the number as the occurance number of the field. It needs to be dynamic because the number of nodes in the record field can be upwards of 100 and I don't want to manually set it for all of the possible records. What I would like as a result is the following:
<table class="fieldGrid" border="0">
<tr>
<td>fruit 1</td>
<td>Apples</td>
</tr>
<tr>
<td>fruit 2</td>
<td>Oranges</td>
</tr>
<tr>
<td>fruit 3</td>
<td>Bananas</td>
</tr>
<tr>
<td>fruit 4</td>
<td>Plums</td>
</tr>
<tr>
<td>vegetable 1</td>
<td>Carrots</td>
</tr>
<tr>
<td>vegetable 2</td>
<td>Peas</td>
</tr>
<tr>
<td>candy 1</td>
<td>Snickers</td>
<tr>
</table>
Thank you
Input:
<record>
<fruit>Apples</fruit>
<fruit>Oranges</fruit>
<fruit>Bananas</fruit>
<fruit>Plums</fruit>
<vegetable>Carrots</vegetable>
<vegetable>Peas</vegetable>
<candy>Snickers</candy>
</record>
XSLT:
<xsl:template match='record'>
<table class='fieldGrid' border='0'>
<xsl:for-each select='*'>
<tr>
<td>
<xsl:value-of select='local-name()'/>
<xsl:text> </xsl:text>
<xsl:number/>
</td>
<td><xsl:value-of select='.'/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
Output:
<table border="0" class="fieldGrid">
<tr>
<td>fruit 1</td>
<td>Apples</td>
</tr>
<tr>
<td>fruit 2</td>
<td>Oranges</td>
</tr>
<tr>
<td>fruit 3</td>
<td>Bananas</td>
</tr>
<tr>
<td>fruit 4</td>
<td>Plums</td>
</tr>
<tr>
<td>vegetable 1</td>
<td>Carrots</td>
</tr>
<tr>
<td>vegetable 2</td>
<td>Peas</td>
</tr>
<tr>
<td>candy 1</td>
<td>Snickers</td>
</tr>
</table>
you must use
<xsl:value-of select="position()"/>
My xsl is working fine when "xmlns" attribute doesn't exist in a node integration_test_results of xml. What i can do in xsl so it will work when "xmlns" attribute exist in integration_test_results node.
Please help me ASAP.
Here i am attaching my xml and xsl file:
Attach xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet href="framework_results.xsl" type="text/xsl" ?>
<integration_test_results xmlns="http://schemas.oracle.com/dm/v2009">
<test>
<name>Reg_Table_test_1</name>
<status>PASSED</status>
<start_time>2010-10-19 05:04:58.011</start_time>
<finish_time>2010-10-19 05:07:29.779</finish_time>
<test_duration>0</test_duration>
<datamover_job>
<status>COMPLETED_SUCCESSFUL</status>
<start_time>2010-10-19 05:04:58.011</start_time>
<finish_time>2010-10-19 05:07:29.779</finish_time>
<job_duration>0</job_duration>
</datamover_job>
</test>
</integration_test_results>
Attach xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://schemas.oracle.com/dm/v2009">
<xsl:template match="ns:integration_test_results">
<html>
<body>
<h2 align="center">Test Report</h2>
<table border="1" align="center">
<tr bgcolor="orange">
<Th colspan="2">Results </Th>
</tr>
<tr>
<th align="Left" bgcolor="orange">Tests passed/Failed/Skipped:</th>
<td>
<xsl:value-of select="count(test[status='PASSED'])" /> /
<xsl:value-of select="count(test[status='FAILED'])" /> /
<xsl:value-of select="count(test[status='RUNNING'])" />
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Started on:</th>
<xsl:for-each select="test">
<xsl:sort select="start_time" order="ascending" data-type="text" />
<xsl:if test="position()=1">
<TD>
<xsl:value-of select="start_time" />
</TD>
</xsl:if>
</xsl:for-each>
</tr>
<tr>
<th align="Left" bgcolor="orange">Total time:</th>
<td>
<xsl:value-of select="sum(test/test_duration[number(.)=number(.)])" />
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Included groups:</th>
<td>
<!-- <xsl:value-of select="" /> -->
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Excluded groups:</th>
<td>
<!-- <xsl:value-of select="" /> -->
</td>
</tr>
</table>
<br></br>
<table border="1">
<tr bgcolor="orange">
<th rowspan="2">Test Name</th>
<th rowspan="2">Test Results</th>
<th rowspan="2">Start Time(sec)</th>
<th rowspan="2">End Time(sec)</th>
<th rowspan="2">Test Duration(sec)</th>
<th rowspan="2">Message</th>
<th colspan="5">DM JOB</th>
</tr>
<tr bgcolor="orange">
<th>Job Name</th>
<th>Job Results</th>
<th>Start Time(sec)</th>
<th>End Time(sec)</th>
<th>Job Duration(sec)</th>
</tr>
<xsl:for-each select="test">
<xsl:sort select="start_time" order="ascending" data-type="text" />
<tr>
<td>
<xsl:value-of select="name" />
</td>
<td>
<xsl:value-of select="status"/>
</td>
<td>
<xsl:value-of select="start_time" />
</td>
<td>
<xsl:value-of select="finish_time" />
</td>
<td>
<xsl:value-of select="test_duration"/>
</td>
<td>
<xsl:value-of select="message" />
</td>
<xsl:for-each select="datamover_job">
<td>
<xsl:value-of select="name" />
</td>
<td>
<xsl:value-of select="status"/>
</td>
<td>
<xsl:value-of select="start_time" />
</td>
<td>
<xsl:value-of select="finish_time" />
</td>
<td>
<xsl:value-of select="job_duration"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
--Thanks
First, properly speaking, there is no xmlns attribute: this is a namespace declaration.
Second, you have an inconsistent way to deal with namespaces in your stylesheet's XPath expression: you have matched the root element with the proper namespace ns:integration_test_results but after that you no longer select it descendants with that namespace.
This is FAQ: Namespace declarations get propagate to descendants.
Try prefixing the rest of the elements just you prefixed
match="ns:integration_test_results"
In the xml you have the default namespace. In the xsl you bind a prefix ns to the same namespace. Therefore, you need to prefix the rest of the elements.
Here is a partial change. Sorry I don't have time to do the rest, but you can figure it out yourself..
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://schemas.oracle.com/dm/v2009">
<xsl:template match="ns:integration_test_results">
<html>
<body>
<h2 align="center">Test Report</h2>
<table border="1" align="center">
<tr bgcolor="orange">
<Th colspan="2">Results </Th>
</tr>
<tr>
<th align="Left" bgcolor="orange">Tests passed/Failed/Skipped:</th>
<td>
<xsl:value-of select="count(ns:test[ns:status='PASSED'])"/> /
<xsl:value-of select="count(ns:test[ns:status='FAILED'])"/> /
<xsl:value-of select="count(ns:test[ns:status='RUNNING'])"/>
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Started on:</th>
<xsl:for-each select="ns:test">
<xsl:sort select="ns:start_time" order="ascending" data-type="text"/>
<xsl:if test="position()=1">
<TD>
<xsl:value-of select="ns:start_time"/>
</TD>
</xsl:if>
</xsl:for-each>
</tr>
<tr>
<th align="Left" bgcolor="orange">Total time:</th>
<td>
<xsl:value-of select="sum(/ns:test/ns:test_duration[number(.)=number(.)])"/>
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Included groups:</th>
<td>
<!-- <xsl:value-of select="" /> -->
</td>
</tr>
<tr>
<th align="Left" bgcolor="orange">Excluded groups:</th>
<td>
<!-- <xsl:value-of select="" /> -->
</td>
</tr>
</table>
<br/>
<table border="1">
<tr bgcolor="orange">
<th rowspan="2">Test Name</th>
<th rowspan="2">Test Results</th>
<th rowspan="2">Start Time(sec)</th>
<th rowspan="2">End Time(sec)</th>
<th rowspan="2">Test Duration(sec)</th>
<th rowspan="2">Message</th>
<th colspan="5">DM JOB</th>
</tr>
<tr bgcolor="orange">
<th>Job Name</th>
<th>Job Results</th>
<th>Start Time(sec)</th>
<th>End Time(sec)</th>
<th>Job Duration(sec)</th>
</tr>
<xsl:for-each select="ns:test">
<xsl:sort select="ns:start_time" order="ascending" data-type="text"/>
<tr>
<td>
<xsl:value-of select="ns:name"/>
</td>
<td>
<xsl:value-of select="ns:status"/>
</td>
<td>
<xsl:value-of select="ns:start_time"/>
</td>
<td>
<xsl:value-of select="ns:finish_time"/>
</td>
<td>
<xsl:value-of select="ns:test_duration"/>
</td>
<td>
<xsl:value-of select="ns:message"/>
</td>
<xsl:for-each select="ns:datamover_job">
<td>
<xsl:value-of select="ns:name"/>
</td>
<td>
<xsl:value-of select="ns:status"/>
</td>
<td>
<xsl:value-of select="ns:start_time"/>
</td>
<td>
<xsl:value-of select="ns:finish_time"/>
</td>
<td>
<xsl:value-of select="ns:job_duration"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
I'm new to xslt. I tried using urn:helper in the stylesheet tag. But it throws the following error.
"Cannot find the script or external object that implements prefix 'urn:Helper'".
Below is the snippet used in my code.
xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myObj="urn:Helper"
xmlns:t="http://microsoft.com/schemas/VisualStudio/TeamTest/2006"
Am I missing something?
Thanks..
edit: complete stylesheet
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myObj="urn:Helper"
xmlns:t="http://microsoft.com/schemas/VisualStudio/TeamTest/2006">
<xsl:param name="today"></xsl:param>
<xsl:param name="results"></xsl:param>
<xsl:param name="pass" select="'Passed'"/>
<xsl:param name="fail" select="'Failed'"/>
<xsl:key name="class-key" match="#className" use="."/>
<xsl:variable name="unique-classes" select="//t:TestMethod/#className[generate-id(.) =generate-id(key('class-key',.))]" />
<xsl:template match="/">
<html>
<body style="font-family:Verdana; font-size:10pt">
<h1>Test Results Summary</h1>
<table style="font-family:Verdana; font-size:10pt">
<tr>
<td>
<b>Run Date/Time</b>
</td>
<td>
</td>
</tr>
<tr>
<td>
Start Time:
</td>
<td>
<xsl:value-of select="myObj:DateTimeToString(//t:TestRun/t:Times/#start)"/>
</td>
</tr>
<tr>
<td>
End Time:
</td>
<td>
<xsl:value-of select="myObj:DateTimeToString(//t:TestRun/t:Times/#finish)"/>
</td>
</tr>
<tr>
<td>
Duration:
</td>
<td>
<xsl:value-of select="myObj:TimeSpan(//t:TestRun/t:Times/#start,//t:TestRun/t:Times/#finish)"/>
</td>
</tr>
<tr>
<td>
<b>Results File</b>
</td>
<td>
<xsl:value-of select="$results"/>
</td>
</tr>
</table>
Coverage Summary
<xsl:call-template name="summary" />
<!--<xsl:call-template name="details" />-->
<xsl:call-template name="details2" />
</body>
</html>
</xsl:template>
<xsl:template name="summary">
<h3>Test Summary</h3>
<table style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt">
<tr>
<td style="font-weight:bold">Total</td>
<td style="font-weight:bold">Failed</td>
<td style="font-weight:bold">Passed</td>
<td style="font-weight:bold">Inconclusive</td>
</tr>
<tr>
<td >
<xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/#total"/>
</td>
<td style="background-color:pink;">
<xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/#failed"/>
</td>
<td style="background-color:lightgreen;">
<xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/#passed"/>
</td>
<td style="background-color:yellow;">
<xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/#inconclusive"/>
</td>
</tr>
</table>
</xsl:template>
<xsl:template name="details">
<h3>Unit Test Results</h3>
<table style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt;">
<tr>
<td style="font-weight:bold">Test Name</td>
<td style="font-weight:bold">Result</td>
<td style="font-weight:bold">Duration</td>
</tr>
<xsl:for-each select="/t:TestRun/t:Results/t:UnitTestResult">
<xsl:sort select="#testName"/>
<tr>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test="#outcome='Failed'">background-color:pink;</xsl:when>
<xsl:when test="#outcome='Passed'">background-color:lightgreen;</xsl:when>
<xsl:otherwise>background-color:yellow;</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<xsl:value-of select="#testName"/>
</td>
<td>
<xsl:choose>
<xsl:when test="#outcome='Failed'">FAILED</xsl:when>
<xsl:when test="#outcome='Passed'">Passed</xsl:when>
<xsl:otherwise>Inconclusive</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:value-of select="#duration"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="details2">
<h3>Unit Test Results</h3>
<table border="0" style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt;">
<xsl:for-each select="$unique-classes">
<xsl:sort />
<xsl:variable name="curClass" select="."/>
<xsl:variable name="return" select="myObj:GetClassInformation($curClass)"/>
<!--<xsl:for-each select="//TestRun/tests/value/testMethod[className=$curClass]">-->
<tr>
<td valign="bottom" style="background-color:beige;font-weight:bold;" colspan="3">
<font>
<xsl:value-of select="concat('',$return/className)"/>
</font>
</td>
</tr>
<tr>
<td style="font-weight:bold">Test Name</td>
<td style="font-weight:bold">Result</td>
<td style="font-weight:bold">Duration</td>
</tr>
<xsl:for-each select="//t:UnitTest/t:TestMethod[#className=$curClass]">
<xsl:sort select="#name"/>
<xsl:variable name="testid" select="../#id"/>
<xsl:for-each select="//t:UnitTestResult[#testId=$testid]">
<xsl:call-template name="classRunsDetail">
<xsl:with-param name="testid" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
<tr>
<td style="border-bottom:0px solid black;height:1px;background-color:black" colspan="3"></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="classRunsDetail">
<xsl:param name="testid"/>
<tr>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test="#outcome = $fail">background-color:pink;</xsl:when>
<xsl:when test="#outcome = $pass">background-color:lightgreen;</xsl:when>
<xsl:otherwise>background-color:yellow;</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<xsl:value-of select="#testName"/>
</td>
<td>
<xsl:choose>
<xsl:when test="#outcome = $fail">FAILED</xsl:when>
<xsl:when test="#outcome = $pass">Passed</xsl:when>
<xsl:otherwise>Inconclusive</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:value-of select="#duration"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
There is no problem with your xsl:stylesheet element.
The problem is here:
<xsl:value-of select="myObj:DateTimeToString(//t:TestRun/t:Times/#start)"/>
From http://www.w3.org/TR/xslt#section-Extension-Functions
If a FunctionName in a FunctionCall
expression is not an NCName (i.e. if
it contains a colon), then it is
treated as a call to an extension
function. The FunctionName is expanded
to a name using the namespace
declarations from the evaluation
context.
If the XSLT processor does not have an
implementation of an extension
function of a particular name
available, then the function-available
function must return false for that
name. If such an extension function
occurs in an expression and the
extension function is actually called,
the XSLT processor must signal an
error.
The answer: You are missing the extension function implementation.
So, you must provide details of your processor and re-ask what is the specific way that your processor is linked to the implementation of extended functions.
I see you grabbed that little helper object from this post. It seems right, but make sure you are using the C# code to actually do the transform.