XSLTといってもいわゆる「文書型」のXMLを変換するのと、「データ型」のXMLを変換するのとでは事情が変わります.私はもっぱら「文書型」のXMLの方しかやっていないので、数値型の詳細や演算子に触れる機会がなかったのですが、見る機会がありましたので紹介します.
まずXPath2.0では、扱える数値型の型が大きく変わりました.XPath1.0では数値といえばnumber型(実体はdouble型)しかなかったのですが、XPath2.0ではXML Schemaで定義された以下の数値型が使えます.
xs:decimal
xs:float
xs:double
xs:integer
xs:float
xs:double
xs:integer
XML Schemaではこれ以外にも、xs:integerの継承型としてxs:short、xs:byteなどがありますが、これらはSchema AwareなXSLTプロセッサでないと使うことができません.(オープンソースバージョンのSaxonでは使うことができません.saxonicaでエンタープライズ版を買う必要があります.)
AltovaXML.exeはSchema Awareですので次のようなxs:integerから派生した型をつかうことができます.
xs:byte
xs:int
xs:long
xs:negativeInteger
xs:nonNegativeInteger
xs:nonPositiveInteger
xs:positiveInteger
xs:short
xs:unsignedByte
xs:unsignedInt
xs:unsignedLong
xs:unsignedShort
xs:int
xs:long
xs:negativeInteger
xs:nonNegativeInteger
xs:nonPositiveInteger
xs:positiveInteger
xs:short
xs:unsignedByte
xs:unsignedInt
xs:unsignedLong
xs:unsignedShort
例えばこんな具合です.
<xsl:variable name="us" select="xs:unsignedShort(5)" as="xs:unsignedShort"/>
<xsl:variable name="us2" select="xs:unsignedShort(7)" as="xs:unsignedShort"/>
<xsl:variable name="resultUsDiv" select="$us div $us2" as="xs:anyAtomicType"/>
<xsl:message select="'$resultUsDiv instance of xs:decimal=',$resultUsDiv instance of xs:decimal, 'result=', $resultUsDiv"/>
<xsl:variable name="us2" select="xs:unsignedShort(7)" as="xs:unsignedShort"/>
<xsl:variable name="resultUsDiv" select="$us div $us2" as="xs:anyAtomicType"/>
<xsl:message select="'$resultUsDiv instance of xs:decimal=',$resultUsDiv instance of xs:decimal, 'result=', $resultUsDiv"/>
これは次のように出力されます.
XSL message: $resultUsDiv instance of xs:decimal= true result= 0.7142857142857142857142857142
でもコードを見てわかるとおり、わざわざこのような型を意識的に使うことはないでしょう.(やっかいで仕方がありません)やはり、XML Scemaで入力するXMLの要素や属性のデータ型が定義されている場合に使うのが自然です.
せっかくSchema AwareなAltovaXML.exeを使ったので、ちょっと脱線して、XML Schemaで型付けされた入力XMLデータをどのようにスタイルシートでその型にマッピングするのか試してみました.
[入力XMLファイル]
<?xml version="1.0" encoding="UTF-8" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="input_schema.xml">
<product name="鉛筆">
<price maker="A" value="100"/>
<price maker="B" value="110"/>
<price maker="C" value="150"/>
</product>
</data>
<?xml version="1.0" encoding="UTF-8" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="input_schema.xml">
<product name="鉛筆">
<price maker="A" value="100"/>
<price maker="B" value="110"/>
<price maker="C" value="150"/>
</product>
</data>
[XML Schema (input_schema.xml)]
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data" type="dataType"/>
<xs:complexType name="dataType">
<xs:sequence>
<xs:element ref="product" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="product" type="productType"/>
<xs:complexType name="productType">
<xs:sequence>
<xs:element ref="price" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:element name="price" type="priceType"/>
<xs:complexType name="priceType">
<xs:attribute name="maker" type="xs:string"/>
<xs:attribute name="value" type="xs:short"/>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="data" type="dataType"/>
<xs:complexType name="dataType">
<xs:sequence>
<xs:element ref="product" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="product" type="productType"/>
<xs:complexType name="productType">
<xs:sequence>
<xs:element ref="price" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:element name="price" type="priceType"/>
<xs:complexType name="priceType">
<xs:attribute name="maker" type="xs:string"/>
<xs:attribute name="value" type="xs:short"/>
</xs:complexType>
</xs:schema>
<xsl:variable name="valueIsShort" select="data(/data[1]/product[1]/price[1]/@value) instance of xs:short" as="xs:boolean"/>
<xsl:message select="'$valueIsShort=',$valueIsShort,"/>
<xsl:message select="'$valueIsShort=',$valueIsShort,"/>
結果は
XSL message: $valueIsShort= true
さて数値型でxs:integerが使えるようになったので、演算子も追加されています.従来除算はdivだけでしたが整数除算のidivが加わりました.
<xsl:message select="'7 idiv 3 =',7 idiv 3"/>
は、
7 idiv 3 = 2
と出力されます.
*Altova XMLは以下からダウンロードできます.無料で使えるSchema Awareなプロセッサは貴重なので一度お試しください.私の使っているのはAltova XML® 2010ですが、AltovaXML® 2011 になっているようです.(Saxonに比べてAltovaはエラーメッセージがそっけないですが...)