Создать HTML TD ячейку, когда отсутствует узел или атрибут
Я работаю над улучшением некоторых таблиц стилей, которые унаследовали, и преобразованием их из использования <xsl:for-each>
в <xsl:apply-templates>
, Очень упрощенная версия одного из файлов XML, с которым я буду работать:
<Root>
<Row ID="123" Region="AMS">
<First>Graham</First>
<Last>Smith</Last>
<Sales>12345.85</Sales>
<Team>Team A</Team>
</Row>
<Row id="321">
<First>John</First>
<Last>Brown</Last>
<Sales>18765.85</Sales>
<Team>Team C</Team>
</Row>
<Row id="456" Region="EMEA">
<First>Anne</First>
<Last>Jones</Last>
<Sales>34567.85</Sales>
<Team>Team B</Team>
</Row>
</Root>
У меня есть новая таблица стилей:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:variable name="RowCount" select="count(/*/*)"/>
<xsl:template match="/@* | node()">
<style>
body * {font-family:Arial;font-size:11pt}
table {border-collapse:collapse}
td {border-bottom:1px solid #D8D8D8;padding:7px}
tr.row1 {background:#F9F9F9;}
td.tdHeader {border-bottom:2px solid #DDD;font-weight:700}
</style>
<table>
<thead>
<tr>
<xsl:apply-templates select="*[1]/@*" mode="headerAttributes" />
<xsl:apply-templates select="*[1]/*" mode="headerFields"/>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="*"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="/*/*/@*" mode="headerAttributes">
<td class="tdHeader">
<xsl:value-of select="name()" />
</td>
</xsl:template>
<xsl:template match="/*/*/*" mode="headerFields">
<td class="tdHeader">
<xsl:value-of select="name()" />
</td>
</xsl:template>
<xsl:template match="/*/*">
<tr class="row{position() mod 2}">
<xsl:apply-templates select="@*" mode="attributes"/>
<xsl:apply-templates select="*" mode="fields"/>
</tr>
</xsl:template>
<xsl:template match="/*/*/@*" mode="attributes">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
<xsl:template match="/*/*/*" mode="fields">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
но из-за отсутствия второго узла в XML <Region>
атрибут, ячейки в результате выровнены неправильно, имя в столбце "Регион", фамилия в столбце "Имя" и т. д. Это также происходит, если в узле Row отсутствует дочерний узел. например, нет элемента команды
Я пытался проверить наличие отсутствующего узла перед вызовом apply-template и внутри двух последних шаблонов, но безрезультатно.
Есть идеи? Что мне здесь не хватает? Я только начинаю разбираться в этом с использованием apply-templates, но с другими методами написания таблиц стилей я в порядке.
1 ответ
Предварительно, это работает для вашего ввода:
<xsl:template match="Row">
<tr class="row{position() mod 2}">
<td><xsl:apply-templates select="@ID|@id" mode="attr2"/></td>
<td><xsl:apply-templates select="@Region" mode="attr2"/></td>
<xsl:apply-templates select="*" mode="fields"/>
</tr>
</xsl:template>
<xsl:template match="@ID|@id|@Region" mode="attr2">
<b><xsl:value-of select="." /></b>
</xsl:template>
- и вы можете удалить ловушку для mode="attributes"
,
Это заставляет включение <td>..</td>
пара, даже если нет id|ID
или же Region
приписывать.
Saxon 8.8 сообщает об ошибке:
Ось атрибута, начинающаяся с узла document-node(), никогда ничего не выберет
из-за вашего
<xsl:template match="/@* | node()">
Меняя его на <xsl:template match="node()">
или, предпочтительно, чтобы <xsl:template match="Root">
это исправлю. Как я уже сказал в своем комментарии, попробуйте использовать *
как можно меньше. Ссылки на Root
а также Row
могут быть изменены на точные совпадения.