XSLT: если тег существует, примените шаблон; если нет, выберите статическое значение - PullRequest
13 голосов
/ 26 апреля 2011

Я новичок в 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>

Ответы [ 3 ]

12 голосов
/ 27 апреля 2011

Еще проще :

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

Примечание :

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

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

12 голосов
/ 26 апреля 2011

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

<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 должно быть достаточно, поскольку apply-templates ничего не будут делать с дочерними элементами, которые не существуют.

6 голосов
/ 26 апреля 2011

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

<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>
...