代码之家  ›  专栏  ›  技术社区  ›  robinjam

如果给定元素在XSLT中不存在,则输出字符串

  •  1
  • robinjam  · 技术社区  · 15 年前

    我有一个XSLT1.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查询。最初,如果字符没有与之关联的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 回复  |  直到 15 年前
        1
  •  1
  •   Dimitre Novatchev    15 年前

    这种转变 :

    <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> )完全可以使用。

        2
  •  2
  •   Erica    15 年前

    假设给定文档中只有零个或一个匹配项,但它们可能位于该文档中的任何位置,则以下内容可能会满足您的要求:

    <?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”到正确的路径来提高效率。

        3
  •  1
  •   Oded    15 年前

    你可以用 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>