Как сделать вложение элементов в XSLT для условного оформления? - PullRequest
1 голос
/ 20 сентября 2019

Вопрос

Как использовать 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">&lt;</xsl:text>i class=<xsl:text disable-output-escaping="yes">&quot;</xsl:text><xsl:value-of select="Source1GrowthCssClass"/><xsl:text disable-output-escaping="yes">&quot;&gt;</xsl:text><xsl:value-of select="Source1GrowthFormatted"/><xsl:text disable-output-escaping="yes">&lt;</xsl:text>/i<xsl:text disable-output-escaping="yes">&gt;</xsl:text>)</td>
<td><xsl:value-of select="Source2CountFormatted"/> (<xsl:text disable-output-escaping="yes">&lt;i class=&quot;</xsl:text><xsl:value-of select="Source2GrowthCssClass"/><xsl:text disable-output-escaping="yes">&quot;&gt;</xsl:text><xsl:value-of select="Source2GrowthFormatted"/><xsl:text disable-output-escaping="yes">&lt;/i&gt;</xsl:text>)</td>

Орлиные глаза среди вас могут даже заметить, что я использовал пример из учебника, предоставленный Microsoft здесь из <xsl:text disable-output-escaping="yes">&lt;</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 (&lt;i class="clsDecrease"&gt;0.00%&lt;/i&gt;)</td>
    <td>755,412 (&lt;i class="clsDecrease"&gt;0.00%&lt;/i&gt;)</td>
  ...

1 Ответ

1 голос
/ 20 сентября 2019

Синтаксис здесь неправильный:

<i class="<xsl:value-of select="Source1GrowthCss"/>">

Чтобы динамически установить значение атрибута, вы можете использовать xsl:attribute примерно так:

<i>
   <xsl:attribute name="class">
      <xsl:value-of select="Source1GrowthCss"/>
   </xsl:attribute>
</i>

Но это довольномногословно.Идеальным подходом было бы использовать «Шаблоны значений атрибутов», которые намного чище

<i class="{Source1GrowthCss}">

Здесь фигурные скобки указывают, что выражение должно оцениваться, а не выводиться буквально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...