0

I have an xslt that takes and formats an xml, in my code I want to program the logic in case a link element is not present. In such a case i just want to write out the title no link. But I am not getting it to work, perhaps there is a better method. See snippet of code:

EDIT: Added xml, also the if's are left blank and same test because I just have no clue how to fix.

<td>
  <xsl:if test="link=">
    <!-- Look for link, target to blank, the link text is the tittle pulled from xml -->
    <a href="{link}" target="_blank">
      <xsl:value-of select="title" />
    </a>
  </xsl:if>

  <xsl:if test="link=">
    <xsl:value-of select="title" />
  </xsl:if>
</td>

An xml fragment to show how the data comes in.

<movies>

  <!-- 1 -->
  <movie>
    <movieID>0108052</movieID>

    <title>Schindler's List</title>

    <director>Steven Spielberg</director>

    <year>1993</year>

    <genre>Biography,</genre>
    <genre>Drama,</genre>
    <genre>History</genre>


    <link>http://www.imdb.com/title/tt0108052/</link>
  </movie>
  <movies>

2
  • What does your input look like? I would expect link[=] to be an element or attribute, not literal text. (The reason your attempt does not work, by the way, is because you do the exact same test twice.) Commented Oct 24, 2015 at 13:59
  • @Jongware I added some information there, hope it helps. Commented Oct 24, 2015 at 14:04

1 Answer 1

2

The syntax for the xsl:if test=.. statement is wrong. Here it is not a string test but an element test, so it will try to find an element called <link=> – which is actually an invalid element name in XML.

You can simply test (no pun intended) with

<xsl:if test="link">there is a child element called "link"</xsl:if>

and

<xsl:if test="not(link)">there is no child element called "link"</xsl:if>

.. but XSLT is very literal-minded, and so you still might not get what you want. Suppose your input file contains empty <link> elements, such as

<link></link>

or (more insidious)

<link>
</link>

– which is "more insidious" because the element actually contains data.

So a better test is against both the presence of an element <link> and whether or not it actually contains textual data instead of only whitespace. Fortunately, you can use the normalize-space function to first discard all whitespace and then test if there is anything left. The following template does that:

<xsl:template match="movie">
<td>
  <xsl:if test="normalize-space(link)">
    <!-- Look for link, target to blank, the link text is the tittle pulled from xml -->
    <a href="{link}" target="_blank">
      <xsl:value-of select="title" />
    </a>
  </xsl:if>

  <xsl:if test="not(normalize-space(link))">
    <xsl:value-of select="title" />
  </xsl:if>
</td>
</xsl:template>

If you have more than one option to test against, you can chain them in both <xsl:if> sequences, but you have to remember to insert all options in both statements, or you may get a double output of title. A more versatile solution is to use a list of options:

<xsl:template match="movie">
<td>
  <xsl:choose>
    <xsl:when test="normalize-space(link)">
        <!-- Look for link, target to blank, the link text is the tittle pulled from xml -->
        <a href="{link}" target="_blank">
        <xsl:value-of select="title" />
        </a>
    </xsl:when>

    <xsl:otherwise>
        <xsl:value-of select="title" />
    </xsl:otherwise>
  </xsl:choose>
</td>
</xsl:template>

You can add <xsl:when> lines for each case, and only if none of them match, it'll automatically fall through to the default otherwise action, which merely writes out the title.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.