У меня есть xsl:variable
($ features-list), указанный в моем XSL, который содержит фрагмент дерева из внешнего XML-файла.
<xsl:variable name="features-list" select="document('features-list.xml', /)" />
Этот файл содержит список элементов «feature», где значение каждого элемента указывает имя элемента. В XML, который я пытаюсь преобразовать (это на самом деле схема RNG), некоторые элементы имеют атрибуты, которые обычно называются «if-feature», которые указывают, что копия такого элемента (или, скорее, всего поддерева) должна появляться только в преобразованном документ, если такой атрибут отсутствует, ИЛИ, если атрибут появляется, но имеет то же значение, что и один из элементов объекта во внешнем файле. Это может потенциально означать, что целые поддеревья могут быть опущены в результирующем документе, поскольку атрибут «унаследован» от предков.
Я успешно использовал эту переменную для запуска или пропуска определенных шаблонов, используя проверки типа
<xsl:when test="not(@if-feature) or @if-feature and $features-list//*[.=current()/@if-feature]">
</xsl:when>
в любом шаблоне. Но это будет работать только при сравнении записей в списке функций с элементом, который в данный момент обрабатывается шаблоном. Теперь мне нужно что-то вроде этого:
<xsl:apply-templates select="descendant::foo[ancestor-or-self::*[not(@if-feature) or $features-list//*[.=current()/@if-feature]]]"/>
где current () относится к одному из элементов предка или самого себя. Я на самом деле пытаюсь запустить шаблон, основанный на условии, как это: обрабатывать только потомки foo текущего узла, предки (и самого себя) - если у них есть атрибут if-feature - его значение должно соответствовать одному из элемента Feature значения в $ feature-list.
Могу ли я выразить такое условие, используя только XPath? Как?
Будет ли решение XSLT более подходящим здесь? Это идентифицирует нарушающие элементы, но мне не очень помогает из-за ограничений XSLT.
<xsl:for-each select="descendant::foo">
<xsl:for-each select="ancestor-or-self::*">
<xsl:choose>
<xsl:when test="@if-feature and not($features-list//*[.=current()/@if-feature])">
<!-- we have a hit, break and do not proceed - but wait, this is XSLT, not Java -->
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
Стараюсь изо всех сил изучать XSLT 1.0 здесь, поэтому, пожалуйста, воздержитесь от предоставления решений для 2.0.
То, что я пытаюсь сделать, - это извлечь действующую схему ГСЧ из существующей, которая задает поддеревья на основе возможностей. Я на самом деле уже сделал это, но это не работает для ONE крошечного небольшого редкого случая, который сейчас сводит меня с ума. Сквозь стены огня. И кирпичи.
Редактировать: спецификация моего состояния была неясной, поэтому я исправил ее.