0

I have an xslt template that i use for converting data, the one i have right now has a choose statement with a bunch of when clauses for each eventuality, the output given is that it seems to ignore all the when's and just goes straight to the otherwise.

ive removed a couple of when statements to shorten it

Ive been through it step by step, changed the select statement to look at the code=a directly.

Something is wrong with my when but i cant seem to see it

<xsl:for-each select="datafield[@tag='300']">               

<xsl:choose>                            
    <xsl:when test="./subfield[@code='a'] !='' and ./subfield[@code='e'] !='' and ./subfield[@code='c'] !=''">
        <xsl:element name="PhysicalDescription">
            <xsl:value-of select="./subfield[@code='a']" />
        </xsl:element>
        <xsl:element name="CoverColour">
            <xsl:value-of select="./subfield[@code='c']" /> - <xsl:value-of select="./subfield[@code='e']" />
        </xsl:element>
    </xsl:when>

    <xsl:when test="./subfield[@code='a'] !='' and ./subfield[@code='c'] !='' and ./subfield[@code='e'] =''">
        <xsl:element name="PhysicalDescription">
            <xsl:value-of select="./subfield[@code='a']" />
        </xsl:element>
        <xsl:element name="CoverColour">
            <xsl:value-of select="./subfield[@code='c']" />
        </xsl:element>
    </xsl:when>

    <xsl:otherwise>
        <xsl:element name="PhysicalDescription">
            <xsl:value-of select="./subfield[@code='a']" />
        </xsl:element>                               
   </xsl:otherwise>                 
</xsl:choose>

XML Data

    <datafield tag="300" ind1="0" ind2="0">
      <subfield code="a">1-914pp (vol.1)</subfield>
    </datafield>
    <datafield tag="300" ind1="0" ind2="0">
      <subfield code="a">915-2385pp (vol.2)</subfield>
    </datafield>
    <datafield tag="300" ind1="0" ind2="0">
      <subfield code="a">cli, 835p (supp)</subfield>
      <subfield code="e">Pbk</subfield>
    </datafield>
    <datafield tag="300" ind1="0" ind2="0">
      <subfield code="c">navy cover</subfield>
      <subfield code="e">Hbk</subfield>
    </datafield>

It should loop through the datafield[@tag='300'] node and for each one that it finds output a value based on the xsl:when.

it only ever outputs the otherwise statement

  • It would help alot if you showed a sample of your input XML. Thank you! – Tim C Sep 11 '19 at 12:58
  • 1-914pp (vol.1) 915-2385pp (vol.2) – Steven Baker Sep 11 '19 at 13:02
  • Could you edit your question to include your XML in that, as code is hard to read in comments. Also, it would help if you showed a sample which has a `` in, because for your current XSLT, the `xsl:when` statements won't be true unless it had such a subfield element. Thanks! – Tim C Sep 11 '19 at 13:23
  • Updated as mentioned in original post – Steven Baker Sep 11 '19 at 13:26

1 Answers1

0

The problem you have is with expressions of this form....

./subfield[@code='e'] =''

This will only be evaluated to try if a subfield[@code='e'] exists, and its value is an empty string. If there is no subfield[@code='e'] in your XML, then the expression evaluates to false.

What you need to do is write it like this: (Note, the ./ prefix is not really needed in any of your expressions).

not(subfield[@code='e'] !='')

This is like a double-negative, but in the case subfield[@code='e'] does not exist, the expression now gets evaluated to true.

So, for your given XSLT, instead of doing this:

<xsl:when test="./subfield[@code='a'] !='' and ./subfield[@code='c'] !='' and ./subfield[@code='e'] =''">

Do this

<xsl:when test="subfield[@code='a'] !='' and subfield[@code='c'] !='' and not(subfield[@code='e'] !='')">

Do note for your given XSLT, the xsl:when statements need both an "a" and "c" present in the XML, which is not the case for the sample provided.

See http://xsltfiddle.liberty-development.net/ncntCRS as an example.

Tim C
  • 70,053
  • 14
  • 74
  • 93