I have the below XML (table):
<table-wrap id="tbl4" position="float">
<label>Table E3</label>
<caption>
<p></p>
</caption>
<alternatives>
<graphic xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="EEMCS-01-2021-001110.tif"/>
<table frame="hsides">
<colgroup>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
<col align="left"/>
</colgroup>
<thead>
<tr>
<th rowspan="2" align="left">1</th>
<th colspan="4" align="center">2</th>
<th rowspan="2" align="center">3</th>
</tr>
<tr>
<th align="center">4</th>
<th align="center">5</th>
<th align="center">6</th>
<th align="center">7</th>
<th align="center">8</th>
</tr>
</thead>
<tbody>
<tr>
<td>9</td>
<td rowspan="2">10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td rowspan="2">15</td>
</tr>
<tr>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
</tr>
<tr>
<td>21</td>
<td colspan="2">22</td>
<td rowspan="2">23</td>
<td colspan="2">24</td>
<td>25</td>
</tr>
<tr>
<td>26</td>
<td>27</td>
<td>28</td>
<td>29</td>
<td>30</td>
<td>31</td>
</tr>
<tr>
<td rowspan="2">32</td>
<td colspan="2">33</td>
<td>34</td>
<td colspan="2">35</td>
<td rowspan="2">36</td>
</tr>
<tr>
<td>37</td>
<td>38</td>
<td>39</td>
<td>40</td>
<td>41</td>
</tr>
</tbody>
</table>
</alternatives>
</table-wrap>
I want to validate missing tr or td in each based on colspan and rowspan
I would like to explain colspan and rowspan conditions:
If colspan="2" in a td, it means two column entries are merged (spanned) so the count of td in that row will be decreased
If rowspan="2" in a td, it means two-row entries are merged (spanned) so the count of td in next row will be decreased
Is there is an additional column or row in the table I have to throw it as an error.
This is a tough problem, and you have to think quite carefully about edge cases, for example where a cell with colspan="2" partially overlaps a cell with rowspan="2" in the row above. There are many errors possible other than having an additional row or column and I assume you want to catch these too.
There may be faster solutions, but I think the simplest is to have a first pass that creates a temporary data structure of the form
<cell row="1" column="1"/>
<cell row="1" column="2"/>
<cell row="1" column="3"/>
with one entry for each "real" (1 by 1) cell encountered, and then in a second pass check this data structure for discrepancies, e.g. no duplicates (overlapping cells) and no raggedness (max column for all rows must be the same, max row for all columns must be the same).
You'll need to process the rows and columns in the input either using recursion, or if you can use XSLT 3.0 using xsl:iterate, so you can keep track of the current row and column number. Using xsl:iterate it will be something like this:
<xsl:iterate select="tr">
<xsl:param name="currentRow" select="1"/>
<xsl:iterate select="td">
<xsl:param name="currentCol" select="1"/>
.... (see below)
<xsl:next-iteration>
<xsl:with-param name="currentCol"
select="$currentCol + (#colspan, 1)[1]"/>
</xsl:with-param>
</xsl:next-iteration>
</xsl:iterate>
<xsl:next-iteration>
<xsl:with-param name="currentRow"
select="$currentRow + 1"/>
</xsl:with-param>
</xsl:next-iteration>
</xsl:iterate>
Then the processing for a td is fairly straightforward: you just do
<xsl:for-each select="$currentRow to $currentRow + (#rowspan, 1)[1] - 1">
<xsl:variable name="row" select="."/>
<xsl:for-each select="$currentCol to $currentCol + (#colspan, 1)[1] - 1">
<xsl:variable name="col" select="."/>
<cell row="{$row}" col="{$col}"/>
</xsl:for-each>
</xsl:for-each>
Hope this sketch is enough to give you some ideas.
Related
Here is my XML File:
XML contains disk space information of hosts.
`<disk>
<host name="host1">
<partitions>
<partition>/par1</partition>
<diskUsed>60%</diskUsed>
</partitions>
<partitions>
<partition>/par2</partition>
<diskUsed>70%</diskUsed>
</partitions>
</host>
<host name="host2">
<partitions>
<partition>/par1</partition>
<diskUsed>80%</diskUsed>
</partitions>
<partitions>
<partition>/par2</partition>
<diskUsed>90%</diskUsed>
</partitions>
</host>
</disk>`
I want to display as below in html
I was not able to read them by column wise, can you please suggest any ways to do this?
<table>
<tr>
<td>host1</td>
<td>host2</td>
</tr>
<tr>
<td>par1</td>
<td>60%</td>
<td>80%</td>
</tr>
<tr>
<td>par2</td>
<td>70%</td>
<td>90%</td>
</tr>
</table>
Any ideas how it can be done using XSLT?
Sorry Below is the XSL code tried. I cannot copy the code i wrote(in client env). So re-wrote it, sorry for the trouble.
<xsl:variable name="disks" select="disk"/>
<table id="disk">
<tr>
<xsl:foreach select="$disk">
<th><xsl:value-of select="#name"/></th>
</xsl:foreach>
</tr>
<tr>
<xsl:for-each select="$disk">
<xsl:for-each select ="partitions">
<td><xsl:value-of select="diskUsed"/></td>
</xsl:for-each>
</xsl:for-each>
here i am not able to print the partitions name
I have 2 files, file.xml and file.xsl that I have made. I am looking for how to see the result in a browser. From my research I have understood that only IE got an xml parser and that for the others browser I need a servor script.
I have also put these lines at the top of my xml file :
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Employe.xsl"?>
and these lignes at the top of my xsl file :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
However, even when i'm using IE (11) I only have the text without any style that I have put.
I wanted to display the elemnts in a table but there isn't any.
I am giving you my code for the table if there is any mistakes I haven't found, but normaly it is ok.
Here is the xsl code :
<xsl:template match="/">
<html>
<body>
<h2>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan=3> ID </th>
<th colspan=5> Basic Information </th>
<th rowspan=3> Picture </th>
<th colspan=2> Skills enable </th>
</tr>
<tr>
<td rowspan=2> Name </td>
<td colspan=3> Address </td>
<td rowspan=2> Phone Number </td>
<td rowspan=2> Skill 1 </td>
<td rowspan=2> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<xsl:for-each select="List_Of_Employe/Employe">
<xsl:sort select="Name"/>
<tr>
<td><xsl:value-of select="ID"/></td>
<td><xsl:value-of select="Basic_Information/Name"/></td>
<td><xsl:value-of select="Basic_Information/Address/Number"/></td>
<td><xsl:value-of select="Basic_Information/Address/Street"/></td>
<td><xsl:value-of select="Basic_Information/Address/Town"/></td>
<td><xsl:value-of select="Basic_Information/Phone_Number"/><td/>
<td><xsl:value-of select="Photo"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_1"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_2"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and here is my xml code :
<List_Of_Employe>
<Employe>
<ID> 1235 </ID>
<Basic_Information>
<Name> James Bond</Name>
<Address>
<Number > 05 </Number>
<Street> Queen's street </Street>
<Town> London </Town>
</Address>
<Phone_Number> 07876543210 </Phone_Number>
</Basic_Information>
<Photo> James.png </Photo>
<Skills_Enable>
<Skill_1> XML </Skill_1>
<Skill_2> C# </Skill_2>
</Skills_Enable>
</Employe>
<Employe>
<ID> 1236 </ID>
<Basic_Information>
<Name> Sherlock Holmes </Name>
<Address>
<Number > 100 </Number>
<Street> Prince's street </Street>
<Town> London </Town>
</Address>
<Phone_Number> 07765432100 </Phone_Number>
</Basic_Information>
<Photo> Sherlock.png </Photo>
<Skills_Enable>
<Skill_1> JavaScript </Skill_1>
<Skill_2> Python </Skill_2>
</Skills_Enable>
</Employe>
</List_Of_Employe>
Hoping you will be able to help me
Mayeul
Your stylesheet needs some improvement, but you're not far off a solution. It's not a beautiful solution, but it successfully transforms your input XML. (A better solution would have used several templates, not a huge one with several for-each statements).
Clearing up a few things
You say:
From my research I have understood that only IE got an xml parser and that for the others browser I need a servor script
No, that's not true. Every major browser has a decent XML parser. You do not need any server-side code to parse XML. Likewise, every major browser (IE, Chrome, Firefox, Safari) ships with an XSLT processor, though only supporting XSLT 1.0.
However, even when i'm using IE (11) I only have the text without any style that I have put.
Getting nothing but all textual content from the input XML as the result of a transformation usually means: none of your templates could match the input elements. None of your code was applied, and the default action is taken: invoking the built-in templates, that only output all text nodes.
It's unclear to me why no templates should apply in your case, let me know whether the stylesheet I suggest below changes the output.
Stylesheet
I have made the following changes to your stylesheet:
There was a stray <td/> that should be </td>, because it ends a td element.
Added quotes to all attribute values. Attribute values absolutely need to be in quotes ("..."), since the XSLT code must itself be well-formed XML.
An HTML parser can deal with a lot of errors (e.g. unquoted attribute values), but XML parsers are very strict on this.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan="3"> ID </th>
<th colspan="5"> Basic Information </th>
<th rowspan="3"> Picture </th>
<th colspan="2"> Skills enable </th>
</tr>
<tr>
<td rowspan="2"> Name </td>
<td colspan="3"> Address </td>
<td rowspan="2"> Phone Number </td>
<td rowspan="2"> Skill 1 </td>
<td rowspan="2"> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<xsl:for-each select="List_Of_Employe/Employe">
<xsl:sort select="Name"/>
<tr>
<td><xsl:value-of select="ID"/></td>
<td><xsl:value-of select="Basic_Information/Name"/></td>
<td><xsl:value-of select="Basic_Information/Address/Number"/></td>
<td><xsl:value-of select="Basic_Information/Address/Street"/></td>
<td><xsl:value-of select="Basic_Information/Address/Town"/></td>
<td><xsl:value-of select="Basic_Information/Phone_Number"/></td>
<td><xsl:value-of select="Photo"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_1"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_2"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Also consider adding the following line to your stylesheet:
<xsl:output method="html" indent="yes"/>
To make it explicit that you'd like to output HTML.
XHTML Output
<html>
<body>
<h2>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan="3"> ID </th>
<th colspan="5"> Basic Information </th>
<th rowspan="3"> Picture </th>
<th colspan="2"> Skills enable </th>
</tr>
<tr>
<td rowspan="2"> Name </td>
<td colspan="3"> Address </td>
<td rowspan="2"> Phone Number </td>
<td rowspan="2"> Skill 1 </td>
<td rowspan="2"> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<tr>
<td> 1235 </td>
<td> James Bond</td>
<td> 05 </td>
<td> Queen's street </td>
<td> London </td>
<td> 07876543210 </td>
<td> James.png </td>
<td> XML </td>
<td> C# </td>
</tr>
<tr>
<td> 1236 </td>
<td> Sherlock Holmes </td>
<td> 100 </td>
<td> Prince's street </td>
<td> London </td>
<td> 07765432100 </td>
<td> Sherlock.png </td>
<td> JavaScript </td>
<td> Python </td>
</tr>
</table>
</body>
</html>
Rendered Output
I do not have IE to try it out there, but Firefox renders the HTML output to:
Finally, let me be nit-picking for a brief moment, it really should read "Employee", not "Employe".
I'm struggling to get the output to display as required.
I run an xslt 1.0 file that parses every 5 seconds a xml file that contains statistical information.
every 15 minutes we get an additional file to parse which is pulled in as external source.
The parsing is fine but displaying the information fails miserably.
This is the section that creates the output:
<td>
<table cellSpacing="0" border="1" cellPadding="2" style="background-color:lightblue;color:green;font-size:80%;">
<xsl:for-each select="/DialStats/Countries">
<!-- #Country = 15 min 2nd XML file / $Country = 5 sec prim XML file-->
<xsl:if test="#Country = $Country">
<xsl:for-each select="./Products">
<!-- #Product = 15 min 2nd XML file / $Product = 5 sec prim XML file-->
<xsl:if test="#Product = $Product">
<xsl:for-each select="Dispositions">
<xsl:variable name="TSB">
<xsl:if test="#Result = 'Tour / Sale / Booking'">
<xsl:value-of select="#Count"/>
</xsl:if>
</xsl:variable>
<!-- // set multiple variables: -->
<xsl:variable name="ITF">
<xsl:if test="#Result = 'Internal Transfer'">
<xsl:value-of select="#Count"/>
</xsl:if>
</xsl:variable>
<!-- // Now generate the output: -->
<xsl:choose>
<xsl:when test="string-length($TSB)=0 and string-length($NoAgent)=0">
<!-- Don't do anything -->
</xsl:when>
<xsl:when test="string-length($TSB)!=0 and string-length($NoAgent)=0">
<tr>
<td>
<xsl:value-of select="$TSB"/>
</td>
<td> - </td>
<td>TSB</td>
<td>. .</td>
<td colspan="3"></td>
</tr>
</xsl:when>
<xsl:when test="string-length($TSB)=0 and string-length($NoAgent)!=0">
<tr>
<td colspan="3"></td>
<td>. .</td>
<td>
<xsl:value-of select="$NoAgent"/>
</td>
<td>-</td>
<td>No Agent</td>
</tr>
</xsl:when>
<xsl:otherwise>
<tr>
<td>
<xsl:value-of select="$TSB"/>
</td>
<td> - </td>
<td>TSB</td>
<td>. .</td>
<td>
<xsl:value-of select="$NoAgent"/>
</td>
<td>-</td>
<td>No Agent</td>
</tr>
</xsl:otherwise>
</xsl:choose>
<!-- // Generate more of the output: -->
<!-- // Last section -->
<xsl:choose>
<xsl:when test="string-length($OTH)=0">
<!-- Don't do anything -->
</xsl:when>
<xsl:when test="string-length($OTH)!=0">
<tr>
<td>
<xsl:value-of select="$OTH"/>
</td>
<td>-</td>
<td>OTH</td>
<td>. .</td>
<td colspan="3"></td>
</tr>
</xsl:when>
<xsl:otherwise>
<!-- Nothing to do -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</table>
</td>
This generates a table however due to how the XML file contains information it is not consistently in the same spot, it might not be there at all.
I want the information to show on the same place for different blocks.
This is how I want it to display
x - TSB | x - NoAgent
x - OSA | x - LO
x - IP | x - UEE
x - MES | x - SIT
x - NoVM | x - RNA
x - NSR | x - ITF
x - OTH
If the value is 0 then I leave the info blank if both are blank then I want to leave the whole line out.
This is how it however displays
9 - MES |
3 - NoVM |
7 - IP |
| 5 - LO
6 - OTH |
| 6 - RNA
| 4 - SIT
3 - TSB |
Is there a way to created first all variables before creating the output?
I tried that but then I end up in the problem that the variable is out-of-scope.
Looking forward to suggestions
The XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<DialStats>
<Countries Country="France">
<Products Product="Office">
<Dispositions Result="Agent Voicemail / Message" Count="11" />
<Dispositions Result="Did Not Leave Voicemail" Count="37" />
<Dispositions Result="Information Provided" Count="13" />
<Dispositions Result="Lost Opportunity" Count="1" />
<Dispositions Result="No Agent Available" Count="1" />
<Dispositions Result="Ring No Answer" Count="6" />
<Dispositions Result="SIT Tone" Count="3" />
<Dispositions Result="Tour / Sale / Booking" Count="7" />
</Products>
</Countries>
<Countries Country="Italy">
<Products Product="Office">
<Dispositions Result="Did Not Leave Voicemail" Count="1" />
<Dispositions Result="Information Provided" Count="6" />
<Dispositions Result="Non-Sales Related" Count="1" />
<Dispositions Result="Other" Count="6" />
<Dispositions Result="Ring No Answer" Count="7" />
<Dispositions Result="SIT Tone" Count="5" />
<Dispositions Result="Updated Existing Enquiry" Count="13" />
</Products>
</Countries>
<Countries Country="Netherlands">
<Products Product="Office">
<Dispositions Result="Agent Voicemail / Message" Count="1" />
<Dispositions Result="Information Provided" Count="17" />
<Dispositions Result="Ring No Answer" Count="3" />
<Dispositions Result="Tour / Sale / Booking" Count="2" />
</Products>
</Countries>
</DialStats>
Many different Countries possible.
Thanks
(edited)
I would suggest you try a different approach. The following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="categories">
<category row="1">Agent Voicemail / Message</category>
<category row="1">Did Not Leave Voicemail</category>
<category row="1">Information Provided</category>
<category row="1">Lost Opportunity</category>
<category row="1">No Agent Available</category>
<category row="1">Ring No Answer</category>
<category row="2">SIT Tone</category>
<category row="2">Tour / Sale / Booking</category>
<category row="2">Non-Sales Related</category>
<category row="2">Other</category>
<category row="2">Updated Existing Enquiry</category>
</xsl:variable>
<xsl:variable name="col-set" select="exsl:node-set($categories)/category" />
<xsl:template match="/">
<xsl:for-each select="DialStats/Countries">
<xsl:variable name="country" select="." />
<table border="1" style="width:30%; display:inline-block">
<tr>
<th colspan="{count($col-set[#row='1'])}">
<xsl:value-of select="$country/#Country"/>
</th>
</tr>
<tr>
<xsl:for-each select="$col-set[#row='1']">
<th><xsl:value-of select="."/></th>
</xsl:for-each>
</tr>
<tr>
<xsl:for-each select="$col-set[#row='1']">
<td>
<xsl:value-of select="$country/Products/Dispositions[#Result=current()]/#Count"/>
</td>
</xsl:for-each>
</tr>
<tr>
<xsl:for-each select="$col-set[#row='2']">
<th><xsl:value-of select="."/></th>
</xsl:for-each>
</tr>
<tr>
<xsl:for-each select="$col-set[#row='2']">
<td>
<xsl:value-of select="$country/Products/Dispositions[#Result=current()]/#Count"/>
</td>
</xsl:for-each>
</tr>
</table>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when applied to your input example, will produce:
<?xml version="1.0" encoding="UTF-8"?>
<table border="1" style="width:30%; display:inline-block">
<tr>
<th colspan="6">France</th>
</tr>
<tr>
<th>Agent Voicemail / Message</th>
<th>Did Not Leave Voicemail</th>
<th>Information Provided</th>
<th>Lost Opportunity</th>
<th>No Agent Available</th>
<th>Ring No Answer</th>
</tr>
<tr>
<td>11</td>
<td>37</td>
<td>13</td>
<td>1</td>
<td>1</td>
<td>6</td>
</tr>
<tr>
<th>SIT Tone</th>
<th>Tour / Sale / Booking</th>
<th>Non-Sales Related</th>
<th>Other</th>
<th>Updated Existing Enquiry</th>
</tr>
<tr>
<td>3</td>
<td>7</td>
<td/>
<td/>
<td/>
</tr>
</table>
<table border="1" style="width:30%; display:inline-block">
<tr>
<th colspan="6">Italy</th>
</tr>
<tr>
<th>Agent Voicemail / Message</th>
<th>Did Not Leave Voicemail</th>
<th>Information Provided</th>
<th>Lost Opportunity</th>
<th>No Agent Available</th>
<th>Ring No Answer</th>
</tr>
<tr>
<td/>
<td>1</td>
<td>6</td>
<td/>
<td/>
<td>7</td>
</tr>
<tr>
<th>SIT Tone</th>
<th>Tour / Sale / Booking</th>
<th>Non-Sales Related</th>
<th>Other</th>
<th>Updated Existing Enquiry</th>
</tr>
<tr>
<td>5</td>
<td/>
<td>1</td>
<td>6</td>
<td>13</td>
</tr>
</table>
<table border="1" style="width:30%; display:inline-block">
<tr>
<th colspan="6">Netherlands</th>
</tr>
<tr>
<th>Agent Voicemail / Message</th>
<th>Did Not Leave Voicemail</th>
<th>Information Provided</th>
<th>Lost Opportunity</th>
<th>No Agent Available</th>
<th>Ring No Answer</th>
</tr>
<tr>
<td>1</td>
<td/>
<td>17</td>
<td/>
<td/>
<td>3</td>
</tr>
<tr>
<th>SIT Tone</th>
<th>Tour / Sale / Booking</th>
<th>Non-Sales Related</th>
<th>Other</th>
<th>Updated Existing Enquiry</th>
</tr>
<tr>
<td/>
<td>2</td>
<td/>
<td/>
<td/>
</tr>
</table>
rendered as:
The table's structure is constant and does not depend on the incoming data.
I have an XML file which i got by exporting a database. now i need to show the xml data in html page as a table. to do so, i have to check the corresponding values for a particular data in the XML file from an XSLT file. since my database is a bit complicated, i am facing difficulties in checking the multiple values of differnt nodes and selecting a corresponding values from another node of the xml file. e.g. i have the following xml data-
<?xml-stylesheet type='text/xsl' href='myXSL.xsl'?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name1>
<names>
<id>5</id>
<class>space</class>
<from>Germany</from>
<fm>
<id>9</id>
<names>5</names>
<name>Vienna</name>
</fm>
<fm>
<id>10</id>
<names>5</names>
<name>Prague</name>
</fm>
</names>
</name1>
<FFrom>
<effect>
<id>11</id>
<DVV>1</DVV>
<SAT>0</SAT>
<DDCC>0</DDCC>
<name>SAA Name</name>
</effect>
<effect>
<id>23</id>
<DVV>0</DVV>
<SAT>0</SAT>
<DDCC>1</DDCC>
<name>SAA Name2</name>
</effect>
</FFrom>
<name2>
<newNames>
<id>1</id>
<name>VSSS Name</name>
<route1>
<id>5</id>
<identifyer>C</identifyer>
<function>abc</function>
<names>4</names>
<naviagtes2>
<id>9</id>
<fm>7</fm>
<effect>2</effect>
</naviagtes2>
<naviagtes2>
<id>10</id>
<fm>8</fm>
<effect>5</effect>
</naviagtes2>
</route1>
</newNames>
<newNames>
<id>6</id>
<name>VEE Name</name>
<route1>
<id>18</id>
<identifyer>C0</identifyer>
<function>abc</function>
<names>5</names>
<naviagtes2>
<id>68</id>
<fm>9</fm>
<effect>11</effect>
</naviagtes2>
<naviagtes2>
<id>69</id>
<fm>10</fm>
<effect>7</effect>
</naviagtes2>
</route1>
</newNames>
</name2>
</root>
I used the following xslt codes
<?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>title</title>
<style type="text/css">
body {
font: 10px Verdana, sans-serif;
color: #000000;
margin: 0;
padding: 0;
}
tr.header2 {
font-style:italic;
}
tr.newNames{
background-color:#6495ED;
margin-top:4px;
}
</style>
</head>
<body><h1><xsl:value-of select="Title" /></h1>
<table width="800px" class="table" cellspacing="0px">
<xsl:for-each select="root/name2/newNames">
<tr class="newNames"><td colspan="12">
<b>NNavigate:</b> <xsl:value-of select="name"/><br/>
<b>NMNaviagate:</b> <xsl:value-of select="route1/function"/>
</td></tr>
<xsl:for-each select="/root/name1/names">
<tr class="names"><td colspan="12">
<b> CClass: </b><xsl:value-of select="class" />
<b> FFrom: </b><xsl:value-of select="from" />
</td></tr>
<tr class="header2">
<td>Route</td>
<td>From</td>
<td align="center">SA</td>
<td align="center">DB</td>
</tr>
<xsl:for-each select="fm">
<tr>
<td class=""><xsl:value-of select="name" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/name" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/SAT" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/DVV" /></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I am stuck in the following point.
if you notice there are fm nodes, effect nodes and naviagtes2 nodes.
in my html page, there will be a table where values of first column come from fm nodes (root/name1/names/fm/name) and values of second column come from effect nodes (root/FFrom/effect/name). in the naviagtes2 nodes, there are fm and effect elements which are equivalent to fm/id and effect/id. that is, naviagtes2 nodes are used to check which values of effect/name will be against fm/name in the table. conditions are like following
root/name1/names/fm/name against root/FFrom/effect/name if
root/name1/names/fm/id = root/name2/newNames/route1/naviagtes2/fm and
root/FFrom/effect/id = root/name2/newNames/route1/naviagtes2/effect
i am new in XSLT programming. Could anyone give me any clue please how to solve that in XSLT ?
in the naviagtes2 nodes, there are fm and effect elements which are
equivalent to fm/id and effect/id. that is, naviagtes2 nodes are used
to check which values of effect/name will be against fm/name in the
table.
I am afraid I still don't understand your question, but in an effort of moving this forward, I'll take a stab (in the dark?) at it.
The following stylesheet uses keys to link each naviagtes2 node to the fm and effect elements whose ids are listed in the naviagtes2 node. Thus each naviagtes2 node creates a {fm,effect} "pair" and these pairs are listed in the resulting table, along with the values fetched from the paired elements:
<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:key name="fm" match="name1/names/fm" use="id" />
<xsl:key name="effect" match="FFrom/effect" use="id" />
<xsl:template match="/">
<table border="1" >
<tr>
<th>id</th>
<th>fm id</th>
<th>effect id</th>
<th>fm name</th>
<th>effect name</th>
</tr>
<xsl:for-each select="root/name2/newNames/route1/naviagtes2">
<tr>
<td><xsl:value-of select="id" /></td>
<td><xsl:value-of select="fm" /></td>
<td><xsl:value-of select="effect" /></td>
<td><xsl:value-of select="key('fm', fm)/name" /></td>
<td><xsl:value-of select="key('effect', effect)/name" /></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
when applied to your example input, the result is:
<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
<tr>
<th>id</th>
<th>fm id</th>
<th>effect id</th>
<th>fm name</th>
<th>effect name</th>
</tr>
<tr>
<td>9</td>
<td>7</td>
<td>2</td>
<td/>
<td/>
</tr>
<tr>
<td>10</td>
<td>8</td>
<td>5</td>
<td/>
<td/>
</tr>
<tr>
<td>68</td>
<td>9</td>
<td>11</td>
<td>Vienna</td>
<td>SAA Name</td>
</tr>
<tr>
<td>69</td>
<td>10</td>
<td>7</td>
<td>Prague</td>
<td/>
</tr>
</table>
which in HTML would be rendered as:
Hopefully this gets you closer to your goal.
Say I have an xml document consisting of a list as shown below:
<Items>
<Item>First Item</Item>
<Item>Second Item</Item>
<Item>Third Item</Item>
<Item>4</Item>
<Item>Five</Item>
</Items>
I want to convert it to a html table with two columns for the Item elements (I'm not fussed at the moment whether it's ordererd top-bottom-left-right or left-right-top-bottom).
<table>
<tr>
<td>First Item</td>
<td>Second Item</td>
</tr>
<tr>
<td>Third Item</td>
<td>4</td>
</tr>
<tr>
<td>Five</td>
<td></td>
</tr>
</table>
I understand I can get a table with a single column with the following xslt transform, but can't figure out how to get multiple columns.
<table>
<xsl:for-each select="Items">
<tr>
<td><xsl:value-of select="Item"/></td>
</tr>
</xsl:for-each>
</table>
Try this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Items">
<table>
<xsl:for-each select="Item[position() mod 2 = 1]">
<xsl:variable name="pos" select="position() - 1" />
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="//Item[position() = ($pos * 2) + 2]"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>