XSLT: если существует тег, примените шаблон; если нет, выберите статическое значение

Я новичок в XSLT в целом, поэтому, пожалуйста, несите меня...

Имея это в виду, я пытаюсь проверить определенный тег в XML. Если он есть, я хочу применить шаблон. Если нет, я хочу добавить его (как пустое значение). В основном это всегда заставляет его быть в конечном выходе. Как мне это сделать?

У меня было что-то вроде этого...

<xsl:choose>
    <xsl:when test="@href">
        <xsl:apply-templates select="country" />
    </xsl:when>
    <xsl:otherwise>
    </xsl:otherwise>
</xsl:choose>

Верхний уровень кода - это то, что я считаю неправильным. Нужно что-то в теге otherwise, и моя часть when ошибочна, я думаю.

<xsl:template match="country">
    <xsl:if test=". != '' or count(./@*) != 0">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:template>

Может ли кто-нибудь помочь? Заранее благодарю вас.

EDIT:

В конце концов мне нужно, по крайней мере, тег <country />, который должен быть в XML. Но возможно, что он не существует вообще. Если он не существует, я должен его ввести. Пример хорошего ввода будет <country>US</country>

Ответы

Ответ 1

В шаблоне для родительского элемента ожидается, что элемент страны будет использоваться, например.

<xsl:template match="foo">
  <xsl:if test="not(country)">
    <country>US</country>
  </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

Вместо foo используйте имя родительского элемента. И, конечно, вы могли бы также делать другие вещи, такие как копирование элемента, я сосредоточился на проверке if. В моем представлении вам действительно не нужен xsl:choose/when/otherwise, xsl:if должен быть достаточным, поскольку шаблоны-приложения не будут ничего делать с дочерними элементами, которые не существуют.

Ответ 2

Еще проще:

<xsl:template match="foo[not(country)]">
        <country>US</country>
    <xsl:apply-templates/>
</xsl:template>

Обратите внимание:

Нет условных инструкций XSLT (например, <xsl:if>) используются, и они не нужны.

Очень часто присутствие <xsl:if> или <xsl:choose> является показателем того, что код может быть реорганизован и значительно улучшен, среди прочего, избавиться от условных инструкций.

Ответ 3

Вам даже не нужен какой-либо Условная обработка. Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="item[not(country)]">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
            <country>Lilliput</country>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

С помощью этого ввода:

<root>
    <item>
        <country>Brobdingnag</country>
    </item>
    <item>
        <test/>
    </item>
</root>

Вывод:

<root>
    <item>
        <country>Brobdingnag</country>
    </item>
    <item>
        <test></test>
        <country>Lilliput</country>
    </item>
</root>