属性と真偽判定
はじめに
属性の有無や属性値によって真偽の判定が変る.いくつか例を考えて整理してみよう.
実行環境は以下の通り.
- Microsoft Windows XP SP2+セキュリティパッチたくさん
- Cygwin 1.5.24(uname -r で確認)
- Saxon-B 9.0.0.2J(インストールしたディレクトリを以下${saxon_home}と表記)
属性がある/ない
3の倍数と3がつく数字のときにアホになるxml(aho01.xml)があるとしよう.アホになる数字には属性ahoがつく.
aho01.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number>1</number>
<number>2</number>
<number aho="true">3</number> <!-- アホになる数字には属性ahoが付く -->
<number>4</number>
<number>5</number>
<number aho="true">6</number>
<number>7</number>
<number>8</number>
<number aho="true">9</number>
<number>10</number>
<number>11</number>
<number aho="true">12</number>
<number aho="true">13</number>
<number>14</number>
<number aho="true">15</number>
</root>
このxmlに以下のxslt(aho01.xsl)を適応すると,アホになる数字(number_become_aho)とアホにならない数字(number_not_aho)を分けて出力できる.
aho01.xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="xml"
encoding="UTF-8"
indent="yes"/>
<xsl:template match="/root">
<root>
<number_become_aho>
<xsl:apply-templates select="number[@aho]"/> <!-- 属性ahoが存在する -->
<!-- <xsl:apply-templates select="number[boolean(@aho)]"/> boolean()はあってもなくても良い -->
</number_become_aho>
<number_not_aho>
<xsl:apply-templates select="number[not(@aho)]"/>
</number_not_aho>
</root>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
実行:
$ java -jar $saxon_home/saxon9.jar -versionmsg:off -s:aho01.xml -xsl:aho01.xsl
実行結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number_become_aho>
<number>3</number>
<number>6</number>
<number>9</number>
<number>12</number>
<number>13</number>
<number>15</number>
</number_become_aho>
<number_not_aho>
<number>1</number>
<number>2</number>
<number>4</number>
<number>5</number>
<number>7</number>
<number>8</number>
<number>10</number>
<number>11</number>
<number>14</number>
</number_not_aho>
</root>
属性値の判定
3の倍数と3がつく数字のときにアホになるxmlを次のように変えよう(aho02.xml).アホになる数字には属性ahoにtrue,アホにならない数字にはfalseを設定する.
aho2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number aho="false">1</number>
<number aho="false">2</number>
<number aho="true">3</number>
<number aho="false">4</number>
<number aho="false">5</number>
<number aho="true">6</number>
<number aho="false">7</number>
<number aho="false">8</number>
<number aho="true">9</number>
<number aho="false">10</number>
<number aho="false">11</number>
<number aho="true">12</number>
<number aho="true">13</number>
<number aho="false">14</number>
<number aho="true">15</number>
</root>
このxmlに前出のaho01.xslを適応すると,全ての数字でアホになる.
実行結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number_become_aho>
<number>1</number>
<number>2</number>
<number>3</number>
<number>4</number>
<number>5</number>
<number>6</number>
<number>7</number>
<number>8</number>
<number>9</number>
<number>10</number>
<number>11</number>
<number>12</number>
<number>13</number>
<number>14</number>
<number>15</number>
</number_become_aho>
<number_not_aho/>
</root>
<xsl:apply-templates select="number[@aho]"/>
は属性ahoがあればtrue,なければfalseであり,属性ahoに入っている値(true/false)は真偽値に影響しないためである.3の倍数と3がつく数字のときにアホになるためにxslを以下のように書換える.
aho02.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="xml"
encoding="UTF-8"
indent="yes"/>
<xsl:template match="/root">
<root>
<number_become_aho>
<xsl:apply-templates select="number[@aho='true']"/> <!-- 属性ahoの値がtrueだったら -->
</number_become_aho>
<number_not_aho>
<xsl:apply-templates select="number[@aho='false']"/> <!-- 属性ahoの値がfalseだったら -->
</number_not_aho>
</root>
</xsl:template>
<xsl:template match="number">
<number>
<xsl:value-of select="."/>
</number>
</xsl:template>
</xsl:stylesheet>
実行結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number_become_aho>
<number>3</number>
<number>6</number>
<number>9</number>
<number>12</number>
<number>13</number>
<number>15</number>
</number_become_aho>
<number_not_aho>
<number>1</number>
<number>2</number>
<number>4</number>
<number>5</number>
<number>7</number>
<number>8</number>
<number>10</number>
<number>11</number>
<number>14</number>
</number_not_aho>
</root>
属性値の有無
xmlを更に変えてみよう(aho03.xml).アホになる数字には属性値ahoにtrue,アホにならない数字には空文字列が入っている.
aho03.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number aho="">1</number>
<number aho="">2</number>
<number aho="true">3</number>
<number aho="">4</number>
<number aho="">5</number>
<number aho="true">6</number>
<number aho="">7</number>
<number aho="">8</number>
<number aho="true">9</number>
<number aho="">10</number>
<number aho="">11</number>
<number aho="true">12</number>
<number aho="true">13</number>
<number aho="">14</number>
<number aho="true">15</number>
</root>
空文字列はfalseとなることを利用して属性ahoを文字列に変換して判断できる.
aho03.xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="xml"
encoding="UTF-8"
indent="yes"/>
<xsl:template match="/root">
<root>
<number_become_aho>
<xsl:apply-templates select="number[string(@aho)]"/> <!-- 空文字以外はtrue -->
</number_become_aho>
<number_not_aho>
<xsl:apply-templates select="number[not(string(@aho))]"/> <!-- 空文字列はfalse -->
</number_not_aho>
</root>
</xsl:template>
<xsl:template match="number">
<number>
<xsl:value-of select="."/>
</number>
</xsl:template>
</xsl:stylesheet>
実行結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number_become_aho>
<number>3</number>
<number>6</number>
<number>9</number>
<number>12</number>
<number>13</number>
<number>15</number>
</number_become_aho>
<number_not_aho>
<number>1</number>
<number>2</number>
<number>4</number>
<number>5</number>
<number>7</number>
<number>8</number>
<number>10</number>
<number>11</number>
<number>14</number>
</number_not_aho>
</root>
ついでにテキストノードの場合
アホになるかならないかが属性ではなくテキストノードに書いてある場合を考えてみた.
aho10.xml:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number value="1"/>
<number value="2"/>
<number value="3">aho</number>
<number value="4"/>
<number value="5"/>
<number value="6">aho</number>
<number value="7"/>
<number value="8"/>
<number value="9">aho</number>
<number value="10"/>
<number value="11"/>
<number value="12">aho</number>
<number value="13">aho</number>
<number value="14"/>
<number value="15">aho</number>
</root>
aho10.xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="xml"
encoding="UTF-8"
indent="yes"/>
<xsl:template match="/root">
<root>
<number_become_aho>
<xsl:apply-templates select="number[text()]"/>
<!-- これでもOK
<xsl:apply-templates select="number[.!='']"/>
<xsl:apply-templates select="number[.='aho']"/> -->
</number_become_aho>
<number_not_aho>
<xsl:apply-templates select="number[not(text())]"/>
<!-- これでもOK
<xsl:apply-templates select="number[.='']"/>
<xsl:apply-templates select="number[.!='aho']"/> -->
</number_not_aho>
</root>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
実行結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<number_become_aho>
<number value="3">aho</number>
<number value="6">aho</number>
<number value="9">aho</number>
<number value="12">aho</number>
<number value="13">aho</number>
<number value="15">aho</number>
</number_become_aho>
<number_not_aho>
<number value="1"/>
<number value="2"/>
<number value="4"/>
<number value="5"/>
<number value="7"/>
<number value="8"/>
<number value="10"/>
<number value="11"/>
<number value="14"/>
</number_not_aho>
</root>
まとめ
属性の有無
xml:
<number>1</number>
<number>2</number>
<number aho="true">3</number>
xsl:
<xsl:apply-templates select="number[@aho]"/>
<xsl:apply-templates select="number[not(@aho)]"/>
属性値の判定
xml:
<number aho="false">1</number>
<number aho="false">2</number>
<number aho="true">3</number>
xsl:
<xsl:apply-templates select="number[@aho='true']"/>
<xsl:apply-templates select="number[@aho='false']"/>
属性値の有無
xml:
<number aho="">1</number>
<number aho="">2</number>
<number aho="true">3</number>
xsl:
<xsl:apply-templates select="number[string(@aho)]"/>
<xsl:apply-templates select="number[not(string(@aho))]"/>
テキストノード
xml:
<number value="1"/>
<number value="2"/>
<number value="3">aho</number>
xsl:
<xsl:apply-templates select="number[text()]"/>
<xsl:apply-templates select="number[not(text())]"/>