Вывод нескольких таблиц в XSLT одновременно
У меня есть документ XML:
<Gym>
<Trainee>
<Trainee_ID>1521</Trainee_ID>
<Trainee_Name>Mary Andersen</Trainee_Name>
<Trainee_Age>23</Trainee_Age>
</Trainee>
<Trainee>
<Trainee_ID>1522</Trainee_ID>
<Trainee_Name>Jane Sellers</Trainee_Name>
<Trainee_Age>56</Trainee_Age>
</Trainee>
<Trainee>
<Trainee_ID>1523</Trainee_ID>
<Trainee_Name>Julie Aniston</Trainee_Name>
<Trainee_Age>32</Trainee_Age>
</Trainee>
<Class>
<Trainee_ID>1521</Trainee_ID>
<Course_ID>A21</Course_ID>
<Class_Room>A1</Class_Room>
</Class>
<Class>
<Trainee_ID>1522</Trainee_ID>
<Course_ID>A22</Course_ID>
<Class_Room>B2</Class_Room>
</Class>
<Class>
<Trainee_ID>1523</Trainee_ID>
<Course_ID>B24</Course_ID>
<Class_Room>B3</Class_Room>
</Class>
<Course>
<Course_ID>A21</Course_ID>
<Course_Title>Yoga</Course_Title>
<Course_Hours_Per_Week>2</Course_Hours_Per_Week>
</Course>
<Course>
<Course_ID>A22</Course_ID>
<Course_Title>Pilates</Course_Title>
<Course_Hours_Per_Week>2</Course_Hours_Per_Week>
</Course>
<Course>
<Course_ID>B24</Course_ID>
<Course_Title>Aerobic</Course_Title>
<Course_Hours_Per_Week>3</Course_Hours_Per_Week>
</Course>
</Gym>
Я хочу сделать 3 таблицы с XSL, с заголовком - именем дочернего элемента (только один раз), подзаголовками - именем элементов внуков (только один раз), а остальные строки и столбцы будут заполнены значениями. из элементов внуков.
Это насколько я получил:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Gym">
<html>
<body>
<xsl:for-each select="*">
<table border="1">
<tr>
<xsl:if test="position()='1' or position()='4' or position()='7'">
<xsl:value-of select="translate(name(.), 'abcdefghijklnmopqrstuvwxyz', 'ABCDEFGHIJKLNMOPQRSTUVWXYZ')"/>
</xsl:if>
</tr>
<tr>
<xsl:if test="position()='1' or position()='4' or position()='7'">
<xsl:for-each select="*">
<th><xsl:value-of select="name(.)"/></th>
</xsl:for-each>
</xsl:if>
</tr>
<tr>
<xsl:for-each select="*">
<th>
<xsl:value-of select="."/>
</th>
</xsl:for-each>
</tr>
</table>
<p></p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
и это вывод:
http://img1.UploadScreenshot.com/images/main/1/2917105455.png
Происходит то, что каждый раз, когда создается новая таблица для каждого подэлемента, но мне нужен умный код, который автоматически создаст все 3 таблицы, а затем создаст заголовки и подзаголовки и после этого будет вводить данные, Что я хочу, это что-то вроде этого (игнорировать цвета и форматирование текста):
Я хочу, чтобы мой XSLT-код создал одну таблицу для каждого экземпляра элемента, затем поместил имя элемента в качестве заголовка, после чего в качестве заголовков поместил один раз подэлементы, а затем заполнил таблицу данными.
1 ответ
Подход, используемый здесь, состоит в том, чтобы использовать мюнхенскую группировку и ключи, чтобы найти отдельные группы и членов из них. Я считаю, что это должно работать:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kCategory" match="/*/*" use="local-name()"/>
<xsl:template match="/*">
<div>
<xsl:apply-templates
select="*[generate-id() = generate-id(key('kCategory', local-name())[1])]" />
</div>
</xsl:template>
<xsl:template match="/*/*">
<table>
<tr class="table-header odd-row">
<th colspan="3">
<xsl:value-of select="local-name()"/>
</th>
</tr>
<tr class="column-headers">
<xsl:apply-templates select="*" mode="colHeader" />
</tr>
<xsl:apply-templates select="key('kCategory', local-name())" mode="row"/>
</table>
</xsl:template>
<xsl:template match="/*/*/*" mode="colHeader">
<td>
<xsl:value-of select="local-name()"/>
</td>
</xsl:template>
<xsl:template match="/*/*" mode="row">
<tr>
<xsl:if test="position() mod 2 = 1">
<xsl:attribute name="class">odd-row</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="*" mode="value" />
</tr>
</xsl:template>
<xsl:template match="/*/*/*" mode="value">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
При запуске на вашем вводном примере это производит:
<div>
<table>
<tr class="table-header odd-row">
<th colspan="3">Trainee</th>
</tr>
<tr class="column-headers">
<td>Trainee_ID</td>
<td>Trainee_Name</td>
<td>Trainee_Age</td>
</tr>
<tr class="odd-row">
<td>1521</td>
<td>Mary Andersen</td>
<td>23</td>
</tr>
<tr>
<td>1522</td>
<td>Jane Sellers</td>
<td>56</td>
</tr>
<tr class="odd-row">
<td>1523</td>
<td>Julie Aniston</td>
<td>32</td>
</tr>
</table>
<table>
<tr class="table-header odd-row">
<th colspan="3">Class</th>
</tr>
<tr class="column-headers">
<td>Trainee_ID</td>
<td>Course_ID</td>
<td>Class_Room</td>
</tr>
<tr class="odd-row">
<td>1521</td>
<td>A21</td>
<td>A1</td>
</tr>
<tr>
<td>1522</td>
<td>A22</td>
<td>B2</td>
</tr>
<tr class="odd-row">
<td>1523</td>
<td>B24</td>
<td>B3</td>
</tr>
</table>
<table>
<tr class="table-header odd-row">
<th colspan="3">Course</th>
</tr>
<tr class="column-headers">
<td>Course_ID</td>
<td>Course_Title</td>
<td>Course_Hours_Per_Week</td>
</tr>
<tr class="odd-row">
<td>A21</td>
<td>Yoga</td>
<td>2</td>
</tr>
<tr>
<td>A22</td>
<td>Pilates</td>
<td>2</td>
</tr>
<tr class="odd-row">
<td>B24</td>
<td>Aerobic</td>
<td>3</td>
</tr>
</table>
</div>
Я полагаю, вы можете справиться с цветами и стилем? Я добавил два class
атрибуты, где я думал, что они будут уместны.
Вы должны быть в состоянии использовать CSS, как показано ниже, чтобы получить нужные вам стили (для этого, безусловно, потребуется некоторая настройка, но это общая идея:
th, td
{
border: 2px solid #9BBA58;
background-color: #E6EDD4;
}
tr.table-header th, tr.column-headers td
{
font-weight: bold;
}
tr.table-header th
{
border-bottom: 4px solid #9BBA58;
}
tr.odd-row th, tr.odd-row td
{
background-color: white;
}