Вопрос
Как использовать XSL для обеспечения условного форматирования, определяемого выполняемым кодом (скажем, увеличением или уменьшением между строками таблицы)?
Фон
Редактировать: Это реализация BackgroundService, работающая с использованием ASP.NET Core в качестве хоста для долгосрочной службы, которая проверяет работоспособностьвнешний ресурс.Это может быть связано с тем, что в .NET Core отсутствуют некоторые функции, присутствующие в .NET Framework, поэтому я решил, что стоит упомянуть
Эта идея возникла потому, что я искал способпростой шаблон HTML, для которого мои объекты данных C # могут быть сопоставлены простым и эффективным способом, не требующим манипулирования StringBuilder.В этой надежде я нашел этот ответ StackOverflow , в котором говорилось, что XSLT будет отличным решением без необходимости полного подхода MVC.
Вот где все это началось (сокращенно для краткости):
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="utf-8"/>
<xsl:template match='/Email'>
<html>
<head>
<style>
<xsl:value-of select="Styles"/>
</style>
</head>
<body>
<h1>Total</h1>
<table id="tblTotal" class="clsPositive">
<tr>
<th>Audit Date</th>
<th>Source 1</th>
<th>Source 2</th>
...
</tr>
<xsl:for-each select="Total/ArrayOfElement/AuditElement">
<xsl:sort select="ReportDate" order="descending"/>
<tr>
<td><xsl:value-of select="ReportDate"/></td>
<td><xsl:value-of select="Source1CountFormatted"/> (<xsl:value-of select="Source1GrowthFormatted"/>)</td>
<td><xsl:value-of select="Source2CountFormatted"/> (<xsl:value-of select="Source2GrowthFormatted"/>)</td>
...
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
После этого у меня появилась идея условно отформатировать процент роста в зависимости от типа представленных данных (вы можете увидеть его начало с помощью атрибута class в таблице, которую я использовалопределить, было ли увеличение или уменьшение положительным или отрицательным).Однако, когда я попытался сделать это, Visual Studio сказал мне, что XSL был искажен:
<td><xsl:value-of select="Source1CountFormatted"/> (<i class="<xsl:value-of select="Source1GrowthCss"/>"><xsl:value-of select="Source1GrowthFormatted"/> </i>)</td>
Я также попробовал подход, в котором свойство "... GrowthFormatted" вернуло бы его встроенный стиль, но всеHTML был сразу же экранирован при разборе в дерево XML для преобразования.Моей последней попыткой перед тем, как прийти сюда, было использование метода xsl: text с disable-output-escaping: "yes".Это привело к чудовищности XSL (обратите внимание на два разных подхода, чтобы увидеть, сработает ли он вообще):
<td><xsl:value-of select="Source1CountFormatted"/> (<xsl:text disable-output-escaping="yes"><</xsl:text>i class=<xsl:text disable-output-escaping="yes">"</xsl:text><xsl:value-of select="Source1GrowthCssClass"/><xsl:text disable-output-escaping="yes">"></xsl:text><xsl:value-of select="Source1GrowthFormatted"/><xsl:text disable-output-escaping="yes"><</xsl:text>/i<xsl:text disable-output-escaping="yes">></xsl:text>)</td>
<td><xsl:value-of select="Source2CountFormatted"/> (<xsl:text disable-output-escaping="yes"><i class="</xsl:text><xsl:value-of select="Source2GrowthCssClass"/><xsl:text disable-output-escaping="yes">"></xsl:text><xsl:value-of select="Source2GrowthFormatted"/><xsl:text disable-output-escaping="yes"></i></xsl:text>)</td>
Орлиные глаза среди вас могут даже заметить, что я использовал пример из учебника, предоставленный Microsoft здесь из <xsl:text disable-output-escaping="yes"><</xsl:text>
и что, спросите вы, было результатом?Что ж, Visual Studio не ошиблась в том, что вложенные элементы не очень хорошо работают с XSL, и вызвала следующее исключение:
XslLoadException: XSLT compile error. An error occurred at , (66, 84). ---> System.Xml.XmlException: '<', hexadecimal value 0x3C is an invalid attribute character. Line 66, poisition 84.
Что касается чрезвычайно многословного подхода, а также сверхпростого подхода,оба они привели к созданию следующего HTML:
...
<tr>
<td>2019-09-19 12:30:40Z</td>
<td>35,991,744 (<i class="clsDecrease">0.00%</i>)</td>
<td>755,412 (<i class="clsDecrease">0.00%</i>)</td>
...