Есть ли элегантный способ добавить несколько классов HTML с помощью XSLT?
Допустим, я преобразовываю тест с множественным выбором из произвольного формата XML в HTML. Каждый выбор будет представлен в виде HTML <li>
тег в итоговом документе. Для каждого варианта я хочу добавить HTML class
из correct
к <li>
если этот выбор был правильным ответом. Кроме того, если этот выбор был выбран пользователем, я хочу добавить класс submitted
к <li>
, Следовательно, если выбор является правильным, а также представленным, <li>
должен иметь class
из correct submitted
,
Насколько я знаю, значения атрибутов, разделенных пробелами, не являются частью модели данных XML и, следовательно, не могут быть созданы напрямую через XSLT. Однако у меня есть ощущение, что есть лучший способ сделать это, чем засорять код одним условным выражением для каждой возможной комбинации классов (что было бы приемлемо в этом примере, но громоздко в более сложных сценариях).
Как я могу решить это элегантным способом?
Пример желаемого результата:
<p>Who trained Obi-Wan Kenobi?</p>
<ul>
<li>Mace Windu</li>
<li class="correct submitted">Qui-Gon Jinn</li>
<li>Ki-Adi-Mundi</li>
<li>Yaddle</li>
</ul>
3 ответа
Во-первых, в пробелах в значениях атрибутов в XML нет ничего плохого: грубо говоря, нормализация значений атрибутов преобразует пробелы в пробелы и объединяет соседние пробелы в один пробел при анализе документа, но пробел определенно разрешен. РЕДАКТИРОВАТЬ: Смотрите ниже для получения дополнительной информации об этом.
Подход Мэтью Уилсона не включает пробел между возможными значениями, как вы упоминаете в своем комментарии к нему. Однако его подход принципиально обоснован. Последняя часть головоломки - ваша неприязнь к избыточным пробелам: их можно устранить с помощью normalize-space
Функция XPath.
Следующая таблица стилей объединяет все биты - обратите внимание, что она ничего не делает со своим входным документом, поэтому в целях тестирования вы можете запустить его для любого XML-документа или даже для самого себя, чтобы убедиться, что вывод соответствует вашим требованиям.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="foo0" select="false()"/>
<xsl:variable name="bar0" select="true()"/>
<xsl:variable name="foo1" select="true()"/>
<xsl:variable name="bar1" select="false()"/>
<xsl:variable name="foo2" select="true()"/>
<xsl:variable name="bar2" select="true()"/>
<xsl:template match="/">
<xsl:variable name="foobar0">
<xsl:if test="$foo0"> foo</xsl:if>
<xsl:if test="$bar0"> bar</xsl:if>
</xsl:variable>
<xsl:variable name="foobar1">
<xsl:if test="$foo1"> foo</xsl:if>
<xsl:if test="$bar1"> bar</xsl:if>
</xsl:variable>
<xsl:variable name="foobar2">
<xsl:if test="$foo2"> foo</xsl:if>
<xsl:if test="$bar2"> bar</xsl:if>
</xsl:variable>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar0)"/>
</xsl:attribute>
</li>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar1)"/>
</xsl:attribute>
</li>
<li>
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($foobar2)"/>
</xsl:attribute>
</li>
</xsl:template>
</xsl:stylesheet>
РЕДАКТИРОВАТЬ: В дополнение к вопросу о пробелах, разделяющих дискретные компоненты в значении атрибута: Спецификация XML определяет ряд возможных допустимых конструкций в качестве типов атрибутов, включая IDREFS и NMTOKENS. Первый случай соответствует производству Имен, а второй случай соответствует производству NMTokens; оба эти произведения определены как содержащие несколько значений соответствующего типа, разделенных пробелами. Таким образом, разделенные пробелами списки значений в качестве значения одного атрибута являются неотъемлемым компонентом информационного набора XML.
Вдобавок ко всему, вы можете создать разделенный пробелами список с чем-то вроде:
<li>
<xsl:attribute name="class">
<xsl:if cond="...">correct</xsl:if>
<xsl:if cond="...">submitted</xsl:if>
</xsl:attribute>
</li>
Насколько я знаю, значения атрибутов, разделенных пробелами, не являются частью модели данных XML и, следовательно, не могут быть созданы напрямую через XSLT.
Если вы не конвертируете в язык XML (который не является HTML, то есть XHTML), вам не следует беспокоиться о достоверности XML для вывода XSLT. Это может быть что угодно, и не должно соответствовать XML!