Вывести строку, если данный элемент не существует в XSLT - PullRequest
1 голос
/ 20 ноября 2010

У меня есть таблица стилей XSLT 1.0, в которой нужно либо вывести значение определенного элемента, если этот элемент существует, либо вывести строку «NULL», если его нет.Как мне это сделать?

Обновление

Документ, с которым я работаю, выглядит примерно так:

<kanjidic2>
    <header>
        <file_version>4</file_version>
        <database_version>2010-325</database_version>
        <date_of_creation>2010-11-20</date_of_creation>
    </header>
    <character>
        <literal>亜</literal>
        <codepoint>
            <cp_value cp_type="ucs">4e9c</cp_value>
            <cp_value cp_type="jis208">16-01</cp_value>
        </codepoint>
    </character>
    <character>
        <literal>?</literal>
        <codepoint>
            <cp_value cp_type="ucs">226F3</cp_value>
            <cp_value cp_type="jis213">2-12-48</cp_value>
        </codepoint>
    </character>
    <!-- Plus a few thousand more <character>s -->
</kanjidic2>

Я пишу таблицу стилей XSLTпревратить вышесказанное в серию запросов MySQL.Первоначально я хотел вывести NULL, если с символом не была связана кодовая точка jis208 (отсюда мой первоначальный вопрос), создав такой запрос:

INSERT INTO `kanji` (`literal`, `ucs`, `jis208`, ...) VALUES ('亜', '4e9c', '16-01', ...);
INSERT INTO `kanji` (`literal`, `ucs`, `jis208`, ...) VALUES ('?, '226F3', NULL, ...);

С тех пор я понял, что могу сделатьXSLT проще и вместо этого создайте более короткий запрос:

INSERT INTO `kanji` (`literal`, `ucs`, `jis208`, ...) VALUES ('亜', '4e9c', '16-01', ...);
INSERT INTO `kanji` (`literal`, `ucs`, `jis213`, ...) VALUES ('?', '226F3', '2-12-48', ...);

Решение

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output method="text" encoding="UTF-8"/>

    <template match="/">
        <apply-templates select="kanjidic2/character"/>
    </template>

    <template match="/kanjidic2/character">
        <text>INSERT INTO `kanji` (`literal`</text>
        <apply-templates select="codepoint/cp_value" mode="first"/>
        <text>) VALUES ('</text>
        <value-of select="literal"/>
        <apply-templates select="codepoint/cp_value" mode="second"/>
        <text>);&#10;</text>
    </template>

    <template match="/kanjidic2/character/codepoint/cp_value" mode="first">
        <text>, `</text>
        <value-of select="@cp_type"/>
        <text>`</text>
    </template>
    <template match="/kanjidic2/character/codepoint/cp_value" mode="second">
        <text>, '</text>
        <value-of select="."/>
        <text>'</text>
    </template>
</stylesheet>

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

Спасибо за помощь.

Ответы [ 3 ]

2 голосов
/ 20 ноября 2010

Если предположить, что в данном документе будет только ноль или одно совпадение, но что они могут быть в любом месте этого документа, то, вероятно, будет делать следующее:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <xsl:choose>
            <xsl:when test="//myelement[@myattribute = 'avalue']"><xsl:value-of select="//myelement[@myattribute = 'avalue']"/></xsl:when>
            <xsl:otherwise>NULL</xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Если они всегда будут находиться в определенной точке в документе, вы можете сделать вышеупомянутое более эффективным, изменив "//" в пути к "myelement" на правильный путь.

1 голос
/ 20 ноября 2010

Это преобразование :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:param name="pDefault">NULL</xsl:param>
 <xsl:variable name="vDefault" select=
  "document('')/*/xsl:param[@name='pDefault']"/>

 <xsl:variable name="vDoc" select="/"/>

 <xsl:template match="/">
     <xsl:value-of select=
      "concat(//myelement[@myattribute='avalue'],
              $vDefault[not($vDoc/*/myelement[@myattribute='avalue'])]
              )"/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<mydoc>
    <myelement myattribute="avalue">Some text</myelement>
    <myelement myattribute="anothervalue">Some more text</myelement>
</mydoc>

создает искомое, правильный результат :

Some text

При применении к этому документу XML :

<mydoc>
    <myelement myattribute="anothervalue">Some more text</myelement>
</mydoc>

снова будет получен нужный, правильный результат :

NULL

Примечание: :

Условная инструкция (<xsl:if> или <xsl:choose> / <xsl:when> / <xsl:otherwise>) не используется ввсе.

1 голос
/ 20 ноября 2010

Вы можете использовать count с xsl:if для вывода различных значений:

<xsl:if test="count(myelement[@myattribute = 'avalue']) = 0">
NULL
</xsl:if>
<xsl:if test="count(myelement[@myattribute = 'avalue']) &gt; 0">
  <xsl:value-of select="myelement" />
</xsl:if>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...