Script to detect ISBN/ISSN

Feb 16, 2012 at 1:00 PM

Hello Yves,

firstly I have to say, nice work you have done here. Very appreciate. I'am working on style for czech citation standard ISO 690:2011 and without your template, I would be lost.

I have one idea, but since I'am not good in coding and programing stuff, I dont know, if it could be implemented or not.

Well, maybe I'am wrong, but as far as I know, there are basicly 9 or 13 numbers in ISBN and 8 numbers in ISSN. Can I somehow analyze form of an element StandardNumber and then, if it has 8 numbers, write ISSN before it and If it has more numbers, write ISBN? I know, this would be tricky one, but if it will work, it would be very smart solution. What do you thing?

 

Vaclav

Coordinator
Feb 17, 2012 at 10:09 AM

There is nothing provided for that but you could easily implement it yourself.

In the code look for the following line:

<xsl:when test="$name = 'Pages' and string($source/b:Pages)">

It is part of a routine which handles all cases. There is none yet for StandardNumber, but you could easily add one. For example, above the previous line you could add something like (untested code, just to give you the idea):

<xsl:when test="$name = 'StandardNumber' and string($source/b:StandardNumber)">
  <xsl:if test="string-length($source/b:StandardNumber) &gt; 8">
    <xsl:text>ISBN: </xsl:text>
  </xsl:if>
  <xsl:if test="string-length($source/b:StandardNumber) = 8">
    <xsl:text>ISSN: </xsl:text>
  </xsl:if>
  <xsl:value-of select="$source/b:StandardNumber" />
</xsl:when>

 

 

 

Feb 19, 2012 at 6:32 PM

Thanks to your little magic advice, I have found working solution. This works good for me and can handle various types of common used serial numbers. It is based on specific rules for standard numbers, which I have found on wikipedia.

 

<!-- Handle standard numbers. -->
<xsl:when test="$name = 'StandardNumber' and string($source/b:StandardNumber)">
	<xsl:if test="number(substring($source/b:StandardNumber, 1,1)) = substring($source/b:StandardNumber, 1,1)">
 		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 8">
			<xsl:text>ISSN </xsl:text>
 		</xsl:if>
		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 10">
 			<xsl:text>ISBN </xsl:text>
		</xsl:if>
 		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 13">
  			<xsl:text>ISBN </xsl:text>
 		</xsl:if>
 		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 26">
  			<xsl:text>ISAN </xsl:text>
 		</xsl:if>
 	</xsl:if>
	<xsl:if test="not(number(substring($source/b:StandardNumber, 1,1)) = substring($source/b:StandardNumber, 1,1))">
		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 12">
			<xsl:text>ISRC </xsl:text>
		</xsl:if>
		<xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 13">
			<xsl:text>ISMN </xsl:text>
		</xsl:if>
	</xsl:if>
<xsl:value-of select="$source/b:StandardNumber" />
</xsl:when>

 

 

Feb 20, 2012 at 3:31 PM
Edited Feb 20, 2012 at 3:43 PM

I realized, that second part could cause some trouble. First section is for standard numbers, that starts with digit, so if anyone write "ISBN 978-..." into b:StandardNumber field, then it won't add anything to that. Second part is for standard numbers, that starts with letter and then, if someone write "ISSN 4444-5555" into b:StandardNumber field, because it starts with letter "I" and without dash it has lenght = 13, the output would be "ISMN ISSN 4444-5555" and that's wrong.

The ISMN number cause more trouble, since it was redesigned in 2008. Now it looks pretty much the same and have the same lenght as ISBN. Only way, that I see, to detect which one is which, is through calculation of the check digit (ARGH).

Well, there's not much of use of ISMN and ISRC for citation these days, so i would recommend temporary remove the second part from the code. So the result is:

 

<!-- Handle standard numbers. -->
<xsl:when test="$name = 'StandardNumber' and string($source/b:StandardNumber)">
<xsl:if test="number(substring($source/b:StandardNumber, 1,1)) = substring($source/b:StandardNumber, 1,1)">
  <xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 8">
    <xsl:text>ISSN </xsl:text>
  </xsl:if>
  <xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 10">
    <xsl:text>ISBN </xsl:text>
  </xsl:if>
  <xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 13">
    <xsl:text>ISBN </xsl:text>
  </xsl:if>
  <xsl:if test="string-length(translate($source/b:StandardNumber, '-','')) = 26">
    <xsl:text>ISAN </xsl:text>
  </xsl:if>
</xsl:if>
<xsl:value-of select="$source/b:StandardNumber" />
</xsl:when>
Apr 14, 2012 at 10:23 AM
Edited Apr 16, 2012 at 4:26 PM

Ok, so I work it out to work with almost all common used standard identifiers. I divided it into two parts:

one part in the place where the previous was

 

<!-- Handle standard numbers. -->
  <xsl:when test="$name = 'StandardNumber' and string($source/b:StandardNumber)">
    <xsl:choose>
    <!-- If string starts with number, sends it to template. This avoid cases, when user writes ISBN/ISSN... themselves. -->
      <xsl:when test="number(substring($source/b:StandardNumber, 1,1)) = substring($source/b:StandardNumber, 1,1)">
        <xsl:call-template name="standard-number">
          <xsl:with-param name="identifier" select="translate($source/b:StandardNumber, '- ','')"/>
        </xsl:call-template>
      </xsl:when>
      <!-- If string starts with letter, it could also be ISRC or old form of ISNM. Old ISNM always starts with letter M, while ISRC always starts with double letter and dash. -->
      <xsl:when test="substring($source/b:StandardNumber, 3, 1) = '-'">
        <xsl:text>ISRC </xsl:text>
      </xsl:when>
      <xsl:when test="starts-with($source/b:StandardNumber, 'M')">
        <xsl:text>ISNM </xsl:text>
      </xsl:when>
    </xsl:choose>
    <xsl:value-of select="$source/b:StandardNumber" />
  </xsl:when>

 

and second part - the template

  <xsl:template name="standard-number">
  
  	<xsl:param name="identifier"/>
    <xsl:choose>
      <xsl:when test="contains($identifier, '/')">
        <xsl:text>DOI </xsl:text>
      </xsl:when>      
      <xsl:when test="string-length($identifier) = 8">
        <xsl:text>ISSN </xsl:text>
      </xsl:when>
      <xsl:when test="string-length($identifier) = 10">
        <xsl:text>ISBN </xsl:text>
      </xsl:when>
      <xsl:when test="string-length($identifier) = 13">
      	<xsl:choose>
          <xsl:when test="substring($identifier, 1, 4) = 9790">
            <xsl:text>ISNM </xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>ISBN </xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:when test="string-length($identifier) = 26">
      	<xsl:text>ISAN </xsl:text>
      </xsl:when>
    </xsl:choose>
    
  </xsl:template>

It maybe isn´t very sophisticated code, but it works great, so if anyone want to use it, feel free to do so.

 

EDIT - improved template code to recognize DOI standard number, which can also begins with number, but i that case contains slash