File: AtWt.xsl

package info (click to toggle)
bodr 10-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,544 kB
  • sloc: xml: 29,107; sh: 494; makefile: 182
file content (173 lines) | stat: -rw-r--r-- 6,865 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?xml version="1.0"?>
<!--
 * This stylesheet simply compares our elements database with
 * the Atomic Weight table by the IUPAC.
 *
 * Run it with: 
 * 
 *     xsltproc -''-html AtWt.xsl http://www.chem.qmul.ac.uk/iupac/AtWt/
 *
 * to debug add: -''-param verbose 1
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:cml="http://www.xml-cml.org/schema"
                xmlns:xml="http://www.w3.org/XML/1998/namespace" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:bo="http://www.blueobelisk.org/dict/terminology" 
                xmlns:boUnits="http://www.blueobelisk.org/dict/units" 
                xmlns:units="http://www.xml-cml.org/units/units" 
                xmlns:siUnits="http://www.xml-cml.org/units/siUnits" 
                xmlns:bibx="http://bibtexml.sf.net/" 
                version="1.0">

<xsl:strip-space elements="*"/>

<xsl:param name="verbose" select="false()"/>

<!--
 * Just catch the first table. We don't need to parse both tables,
 * which just differ in order.
-->
<!-- Table 2007: /descendant::table[1]-->
<!-- Table 2011: /descendant::table[2]-->
<xsl:template match="/">
	<xsl:apply-templates select="/descendant::table[3]"/>
</xsl:template>

<!--
 * Parse the table line by line, going up in the Element number.
 * Don't process the table "header".  
-->
<xsl:template match="table">
	<xsl:apply-templates select="tr[number(td[1]) = true()]">
		<xsl:sort data-type="number" order="ascending" select="td[1]"/>
	</xsl:apply-templates>
</xsl:template>

<!--
 * The basic table layout is: 
 *
 * | No || Symbol || Name || Atomic Weight || Notes |
 *
 * Interesting are only the first 4. We don't care about the notes.
 * The 'Atomic Wt' column can have values with the error value appended
 * inside parenthesis and the values can be surrounded by square
 * brackets. So we need to remove the square brackets and the error
 * value for the atomic weight and extract the error value from
 * inside the parenthesis. If there are no parenthesis, there is no
 * error value.
-->
<xsl:template match="tr">
	<xsl:choose>
		<!-- There *is* an error value inside parenthsis. -->
		<xsl:when test="contains(td[4], '(') and
		                string-length(substring-before(td[4], '('))">

			<xsl:call-template name="compare.AtWt.BODR.tables">
				<xsl:with-param name="iupac.ElementNo" select="normalize-space(td[1])"/>
				<xsl:with-param name="iupac.ElementSy" select="normalize-space(td[2])"/>
				<xsl:with-param name="iupac.Element" select="normalize-space(translate(td[3],'&#x00A0;',' '))"/>
				<xsl:with-param name="iupac.Mass"
				                select="normalize-space(translate(substring-before(td[4], '('), '[]', ''))"/>
				<xsl:with-param name="iupac.Error"
				                select="normalize-space(substring-after(substring-before(td[4], ')'), '('))"/>
			</xsl:call-template>

		</xsl:when>
		<!-- There is *no* error value. -->
		<xsl:otherwise>
			<xsl:call-template name="compare.AtWt.BODR.tables">
				<xsl:with-param name="iupac.ElementNo" select="normalize-space(td[1])"/>
				<xsl:with-param name="iupac.ElementSy" select="normalize-space(td[2])"/>
				<xsl:with-param name="iupac.Element" select="normalize-space(translate(td[3],'&#x00A0;',' '))"/>
				<xsl:with-param name="iupac.Mass"
				                select="normalize-space(translate(td[4], '[]', ''))"/>
			</xsl:call-template>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!--
 * The following template gets: Element number, symbol and name, mass
 * and error value (if any) as extracted from the IUPAC table.
 *
 * Based on the Element number it extracts the same information from
 * our elements database and compares the values. If there is a difference,
 * it errors out with a note, which difference we have.
-->
<xsl:template name="compare.AtWt.BODR.tables">
	<xsl:param name="iupac.ElementNo"/>
	<xsl:param name="iupac.ElementSy"/>
	<xsl:param name="iupac.Element"/>
	<xsl:param name="iupac.Mass"/>
	<xsl:param name="iupac.Error" select="'novalue'"/>

	<xsl:variable name="bodr.node"
	              select="document('elements/elements.xml')//cml:atom[child::cml:scalar[attribute::dictRef='bo:atomicNumber']=$iupac.ElementNo]"/>
	<xsl:variable name="bodr.Element"
	              select="$bodr.node/cml:label[@dictRef='bo:name']/@value"/>
	<xsl:variable name="bodr.ElementSy"
	              select="$bodr.node/cml:label[@dictRef='bo:symbol']/@value"/>
	<xsl:variable name="bodr.Mass"
	              select="$bodr.node/cml:scalar[@dictRef='bo:mass']"/>
	<xsl:variable name="bodr.Error">
		<xsl:choose>
			<xsl:when test="$bodr.node/cml:scalar[@dictRef='bo:mass']/@errorValue">
				<xsl:value-of select="$bodr.node/cml:scalar[@dictRef='bo:mass']/@errorValue"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="'novalue'"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>

	<xsl:if test="$verbose">
		<xsl:message>DEBUG ElementNo. <xsl:value-of select="$iupac.ElementNo"/>
  Name   &lt;<xsl:value-of select="$iupac.Element"/>&gt; <xsl:value-of select="$bodr.Element"/>
  Symbol &lt;<xsl:value-of select="$iupac.ElementSy"/>&gt; <xsl:value-of select="$bodr.ElementSy"/>
  Mass   &lt;<xsl:value-of select="$iupac.Mass"/>&gt; <xsl:value-of select="$bodr.Mass"/>
  Error  &lt;<xsl:value-of select="$iupac.Error"/>&gt; <xsl:value-of select="$bodr.Error"/>
		</xsl:message>
	</xsl:if>

	<xsl:if test="not($iupac.Element = $bodr.Element)
	              or not($iupac.ElementSy = $bodr.ElementSy)
	              or not($iupac.Mass = $bodr.Mass)
	              or not($iupac.Error = $bodr.Error)">
		<xsl:message terminate="no">
ERROR: We differ from the IUPAC AtWt table.
<xsl:choose>
<xsl:when test="not($iupac.Element = $bodr.Element)">
element (IUPAC): <xsl:value-of select="$iupac.Element"/>
element (BODR): <xsl:value-of select="$bodr.Element"/>
</xsl:when>
<xsl:when test="not($iupac.ElementSy = $bodr.ElementSy)">
element:  <xsl:value-of select="$iupac.Element"/>
element symbol (IUPAC): <xsl:value-of select="$iupac.ElementSy"/>
element symbol (BODR): <xsl:value-of select="$bodr.ElementSy"/>
</xsl:when>
<xsl:when test="not($iupac.Mass = $bodr.Mass)">
element:  <xsl:value-of select="$iupac.Element"/>
mass (IUPAC): <xsl:value-of select="$iupac.Mass"/>
mass (BODR): <xsl:value-of select="$bodr.Mass"/>
</xsl:when>
<xsl:when test="not($iupac.Error = $bodr.Error)">
element:  <xsl:value-of select="$iupac.Element"/>
error value (IUPAC): <xsl:value-of select="$iupac.Error"/>
error value (BODR): <xsl:value-of select="$bodr.Error"/>
</xsl:when>
<!-- Last case: We had an error, but the values were all correct??? -->
<xsl:otherwise>
Oops. This shouldn't happen. Something went wrong.
</xsl:otherwise>
</xsl:choose>

Exiting. Fix the database.
</xsl:message>
	</xsl:if>
</xsl:template>

<xsl:template match="*"/>

</xsl:stylesheet>