Это должно работать:
<xsl:variable name="firstcall" select="$topcall[$topcall] |
$focusedcall[not($topcall)]" />
Другими словами, выберите $topcall
, если $topcall
nodeset не пуст; $focusedcall
, если $topcall
набор узлов пуст.
Повторное обновление относительно "это может быть 5-6 узлов":
Учитывая, что может быть 5-6 альтернатив, то есть еще 3-4, кроме $ topcall и $ focuscall ...
Самое простое решение - использовать <xsl:choose>
:
<xsl:variable name="firstcall">
<xsl:choose>
<xsl:when test="$topcall"> <xsl:copy-of select="$topcall" /></xsl:when>
<xsl:when test="$focusedcall"><xsl:copy-of select="$focusedcall" /></xsl:when>
<xsl:when test="$thiscall"> <xsl:copy-of select="$thiscall" /></xsl:when>
<xsl:otherwise> <xsl:copy-of select="$thatcall" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
Однако в XSLT 1.0 это преобразует вывод выбранного результата во фрагмент дерева результатов (RTF: в основном, замороженное поддерево XML). После этого вы не сможете использовать какие-либо существенные XPath-выражения в $firstcall
для выбора вещей из него. Если вам нужно , чтобы сделать выбор XPath на $firstcall
позже, например, select="$firstcall[1]"
, тогда у вас есть несколько вариантов ...
- Поместите эти выборки в
<xsl:when>
или <xsl:otherwise>
, чтобы они произошли до того, как данные будут преобразованы в RTF. Или,
- Рассмотрим расширение
node-set()
, которое преобразует RTF в набор узлов, поэтому вы можете делать из него обычные выборки XPath. Это расширение доступно в большинстве процессоров XSLT, но не во всех. Или,
- Рассмотрите возможность использования XSLT 2.0, где RTF вообще не являются проблемой. На самом деле, в XPath 2.0 вы можете поместить обычные условные выражения if / then / else внутри выражения XPath, если хотите.
- Реализуйте его в XPath 1.0, используя вложенные предикаты, такие как
select="$topcall[$topcall] |
($focusedcall[$focusedcall] | $thiscall[not($focusedcall)])[not($topcall)]"
и продолжайте гнездиться настолько глубоко, насколько это необходимо. Другими словами, здесь я взял выражение XPath для 2 альтернатив выше и заменил $ focuscall на
($focusedcall[$focusedcall] | $thiscall[not($focusedcall)])
На следующей итерации вы замените $ thiscall на
($thiscall[$thiscall] | $thatcall[not($thiscall)])
и т.д.
Конечно, это становится трудным для чтения и подвержено ошибкам, поэтому я бы не стал выбирать этот вариант, если другие неосуществимы.