タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
2 / 35
改訂履歴
項番 日付 バージョン 改訂内容 作成者 備考
1 2010/09/27 1.0 新規作成 株式会社サンテック
2
3
4
5
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
3 / 35
目次1. 概要 .................................................................................................. 5
2.XPath ................................................................................................. 6
2.1. ノード ............................................................................................ 6
2.2. ロケーションパス .................................................................................. 7
2.2.1. ロケーションステップ ........................................................................ 9
2.2.1.1. 軸 .................................................................................... 9
2.2.1.2. ノードテスト ......................................................................... 10
2.2.1.3. 述語(式) ........................................................................... 10
2.2.2. ロケーションパスまとめ ..................................................................... 12
3.XPath ルール記述例 ................................................................................... 13
3.1. 基本パターン(○○を使用してはならない。) ....................................................... 13
3.1.1. 指定したキーワードを違反とする ............................................................. 13
3.1.2. 指定した複数のキーワードを違反とする ....................................................... 14
3.1.3. 指定した複数のキーワードを違反とする 2 ..................................................... 16
3.1.4. 指定したキーワードを含んだ箇所を違反とする ................................................. 18
3.2. 基本パターン + 条件 .............................................................................. 19
3.2.1. 特定の要素が存在した場合、指定したキーワードを違反とする。 ................................. 19
3.2.2. 特定の要素に囲まれているノード集合を違反とする。 ........................................... 21
3.2.3. 特定の要素に囲まれているノード集合を違反とする2 .......................................... 23
3.3. まとめ ........................................................................................... 25
4.XPath ルール実装方法 ................................................................................. 26
5.CX-Checker のノード .................................................................................. 27
5.1.CX-model ......................................................................................... 27
6.CX-model 要素詳細 .................................................................................... 29
6.1.File ............................................................................................. 29
6.2.Define ........................................................................................... 29
6.3.Include .......................................................................................... 29
6.4.Function ......................................................................................... 29
6.5.Global ........................................................................................... 30
6.6.Local ............................................................................................ 30
6.7.Argument ......................................................................................... 30
6.8.Typedecl ......................................................................................... 30
6.9.Prototype ........................................................................................ 31
6.10.Param ........................................................................................... 31
6.11.Type ............................................................................................ 31
6.12.Tag ............................................................................................. 31
6.13.Member .......................................................................................... 32
6.14.Enum ............................................................................................ 32
6.15.Stmt ............................................................................................ 32
6.16.Expr ............................................................................................ 32
6.17.Label ........................................................................................... 33
6.18.hfile ........................................................................................... 33
6.19.macroPattern .................................................................................... 33
6.20.macroBody ....................................................................................... 33
6.21.macroCall ....................................................................................... 33
6.22.ident ........................................................................................... 33
6.23.literal ......................................................................................... 34
6.24.comment ......................................................................................... 34
6.25.op .............................................................................................. 34
6.26.pp .............................................................................................. 34
6.27.no_expand ....................................................................................... 34
6.28.sp .............................................................................................. 34
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
4 / 35
6.29.nl .............................................................................................. 35
6.30.kw .............................................................................................. 35
6.31.T ............................................................................................... 35
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
5 / 35
1. 概要
本ドキュメントはCX-Checkerの独自ルール作成に使用する、XPath(XML Path Language)の記述方法を記載し
たものです。自らのオリジナルルールを作成したいときにこのマニュアルを使用してください。
CX-Checkerは SapidがソースコードをCX-modelに基づいて解析しXMLファイルを出力します。出力されたXML
と、XPathで記述されたルールに準拠しているかを比較しチェックを行います。
SDB
h o g e . c
2. 出力
XPathルール
MI SRA-C
. x ml
MI SRA-C
. x ml
…
CX-Checker
Sapid1 . 解析
SPEC
h o g e . x ml
4. 出力3. チェック
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
6 / 35
2. XPath
本項目ではXPathの基本的な概念、用語を記述します。XPathとはXMLの位置を指定するための言語です。以
下にXMLと XPathの簡単な概要図を示します。
XPath
XML
2.1. ノード
XPathは要素がツリー状に構成されます。ツリーの節の部分をノードと呼びます。
以下にノードの種類を示します。
ノード種類 説明
rootノード 最上位のノード
要素ノード XMLの要素を表すノード
<要素名></要素名>のように記述する。
属性ノード 要素内で指定された属性を表すノード
<要素名 属性名=”属性値”></要素名>のように記述する。
テキストノード 開始タグと終了タグで挟まれた文字列データ
<要素名>テキスト</要素名>のように記述する。
また、現在の自分がいるノードをカレントノード, カレントノードから相対パスで指定されるノードをコンテ
キストノードと呼びます。CX-Checkerのカレントノードはrootノードになります。
ソースコードをSapidで解析したとき出力されるXMLを例に、各ノードがどの種類のノードなのかを示します。
ソースコード
int var1, var2;
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
7 / 35
XML
<?xml version="1.0" ?>
<!DOCTYPE CX SYSTEM "CX-model.dtd">
<CX>
<File id="s8388610">
<Global id="s33554434">
<Type>
<kw sort="type">int</kw>
</Type>
<sp></sp>
<ident defid="s33554433" type_id="s83886080">var1</ident>
<op>,</op>
<sp></sp>
<ident defid="s33554434" type_id="s83886080">var2</ident>
</Global>
<op>;</op>
<sp />
<nl line="1" offset="16" />
</File>
</CX>
2.2. ロケーションパス
各ノードの種類がわかったところで、次はノードの指定方法についてご説明します。ノードを指定するにはロ
ケーションパスというものを使用します。後に説明しますが、/CX/File/Global/Type/kw という形のものをロ
ケーションパスといいます
CX-Checkerではロケーションパスで指定されたノードの有無をチェックし、違反の検出を行います。
XPathでローケーションパスを記述するときは、要素ノードを”/”で区切り指定します。
例えば、下記のXMLの要素ノード<kw>のテキストノードのintを指定したい場合、ロケーションパス
は/CX/File/Global/Type/kw/text()になります。また、rootノードがカレントノードですので頭の”/”を抜
いて、CX/File/Global/Type/kw/text()とコンテキストノードで指定することもできます。
<?xml version="1.0" ?>
<!DOCTYPE CX SYSTEM "CX-model.dtd">
<CX>
<File id="s8388610">
<Global id="s33554434">
要素ノード
属性ノード
テキストノード
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
8 / 35
<Type>
<kw sort="type">int</kw>
</Type>
<sp></sp>
<ident defid="s33554433" type_id="s83886080">var1</ident>
<op>,</op>
<sp></sp>
<ident defid="s33554434" type_id="s83886080">var2</ident>
</Global>
<op>;</op>
<sp />
<nl line="1" offset="16" />
</File>
</CX>
ロケーションパスの指定には簡略して記述できるものがあります。
以下に簡略して記述できる構文を挙げます。
構文 意味
para コンテキストノードの子要素paraを選択する
* コンテキストノードのすべての子要素を選択する
text() コンテキストノードのすべてのテキストノードを選択する
@element コンテキストノードのelement属性を選択する
@* コンテキストノードのすべての属性を選択する
para[n] コンテキストノードのn番目の子要素paを選択する
//para ルートノードの子孫からすべての要素paraを選択する
. コンテキストノードを選択する
.. コンテキストノードの親ノードを選択する。
前述の例CX/File/Global/Type/kw/text()は以下のように簡略して記述することができます。
CX/File/Global/Type/kw/text() ⇒ //kw/text()
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
9 / 35
2.2.1. ロケーションステップ
ロケーションパスの”/”で区切られた部分をロケーションステップといいます。
例: CX/File/Global/Type/kw/text()
ロケーションステップは以下のものから構成されます。
表2-6
軸 選択するノードとコンテキストノードの位置関係を選択する
ノードテスト 選択するノードのタイプと名前を指定する
述語 選択するノード集合を、任意の式で細かく指定する
上記のものを組み合わせ、コンテキストノードから選択するノードの位置を指定します。
記述方式は以下のように記述します。
記述方式: 軸::ノードテスト[述語(式)]
記述例: //Type/following-sibling::ident[position() = 2]
それでは次に //Type/following-sibling::ident[position() = 2] というXPathを元に、軸、ノードテスト、
述語の説明を行っていきます。
2.2.1.1. 軸
軸とはコンテキストノードの祖先、子孫などをまとめて指定するものです。
軸の指定方法は以下のものがあります。
軸の種類 意味 省略記号
ancestor 自分の祖先のノード
ancestor-or-self 自分自身とその祖先
attribute 自分の属性ノード @
child 子ノード 記述しない
descendant 自分の子孫ノード
descendant-or-self 自分自身とその子孫 //
following 後続するすべてのノード
following-sibling 自分より後続の兄弟
namespace 自分の名前空間ノード
parent 親ノード ..
preceding 先行するすべてのノード
ロケーションパス
ロケーションステップ
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
10 / 35
preceding-sibling 自分より先行する兄弟
self 自分自身 .
以下に例を挙げます。※ 部分が軸です。
例)要素Typeの後続する兄弟から2番目のidentを指定する。
//Type/following-sibling::ident[position() = 2]
2.2.1.2. ノードテスト
対象とするノードの種類を指定するものをノードテストといいます。※ 部分ノードテストです。
例)要素Typeの後続する兄弟から2番目のidentを指定する。
//Type/following-sibling::ident[position() = 2]
2.2.1.3. 述語(式)
述語とは、ノード集合中から選択するノードの条件を指示する式です。
軸、ノードテストで指定したノード集合から条件にあったものを選択するときに使用します。
述語の条件式には、関数を使用することができます。
以下に主な関数を記述します。
last関数
説明:コンテキストノードの最後の要素ノードを選択する。
記述:ロケーションパス[last()]
戻り値:数値型 ロケーションパスで指定したコンテキストノードの最後の要素番号
例://track[last()]
…コンテキストノードである要素trackから、最後の要素trackを選択する。
position関数
説明:コンテキストノードの集合内で何番目の要素かを返す。
述語に[position() = 2]と記述した場合、単に[2]と書いたのと同義である。
記述:ロケーションパス[position() = n]
戻り値:数値型 ロケーションパスで指定したノード集合の要素番号、先頭は1から始まる。
例://track[position() = 2] or //track[2]
…すべての要素trackをノード集合とし、その中の2番目の要素を選択する。
count関数
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
11 / 35
説明:コンテキストノード内の引数に指定した要素のノード数を返す。
記述:ロケーションパス[count(要素名)]
戻り値:数値型 指定したノード集合の合計要素数。
例://track[position() = (count(track) – 2]
…すべての要素trackをノード集合とし、最後から2つ前の要素を選択する。
starts-with関数
説明:引数で指定した文字列1が文字列2で始まっている場合にTRUEを返す。
それ以外の場合はFALSEを返す。
文字列に要素ノードを入れると、その要素のテキストノードを文字列1とする。
指定した要素ノードが複数のノード集合のとき、すべての要素のテキストノードが
条件を満たす場合のみ TRUEを返す。
記述:ロケーションパス[ starts-with(文字列1, 文字列2) ]
戻り値:BOOLEAN型
例:starts-with(track, 'Guiter')
…要素trackのテキストノードがGuiterで始まっているか判定する。
contains関数
説明:引数で指定した文字列1が文字列2を含む場合にTRUEを返す。それ以外はFALSEを返す。
文字列1に要素名を入れると、その要素のテキストノードを文字列1とする。
文字列1に属性を入れると、コンテキストノードの属性値が文字列1となる。
記述:ロケーションパス[ contains(文字列1, 文字列2) ]
戻り値:BOOLEAN型
例:contains(track, 'Don't')
…要素trackのテキストノードがDon'tを含むか判定する。
string-length関数
説明:引数で指定した文字列の文字数を返す。
引数を省略した場合はコンテキストノードのテキストノードが文字列となる。
引数に要素名を入れると、その要素のテキストノードを文字列とする。
引数に属性を入れると、コンテキストノードの属性値が文字列となる。
記述:string-length(文字列)
戻り値:数値 引数で指定した文字列の文字数
例:string-length(track[position() = 1])
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
12 / 35
…要素trackの 1番目のテキストノードの文字数を返す。
※ 部分が述語です。
例)要素Typeの後続する兄弟から2番目のidentを指定する。
//Type/following-sibling::ident[position() = 2]
また、述語には以下の演算子を使用することができます。
演算子 意味 優先順位
or 論理和 7
and 論理責 6
= 等しい 5
!= 等しくない 5
< 比較 4
<= 比較 4
> 比較 4
>= 比較 4
+ 和 3
- 差 3
* 積 2
div 商 2
mod 余り 2
| 1
上記の演算子は評価式中のみ有効です。
例)要素Typeの後続する兄弟からテキストがvar2の2番目のidentを指定する。
//Type/following-sibling::ident[( position() = 2 ) and ( text()=”var2” )]
2.2.2. ロケーションパスまとめ
・コンテキストノードから別のノードを指定する式をロケーションパスと呼ぶ。
・ロケーションパスは1つ以上のロケーションステップから構成される。
・ロケーションステップは軸、ノードテスト、述語(式)から構成される。
・軸はコンテキストノードから祖先、子孫などのノード集合をまとめて指定する。
・ノードテストはノード集合中から選択するノードの種類を指定する。
・述語(式)はノード集合中から選択するノードの条件を指定する。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
13 / 35
3. XPathルール記述例
以上のXPathの説明を踏まえ、本項目では、MISRA-Cで公開しているルールを例に挙げ、パターン別にXPath
の記述方法を説明します。なお、XPathでルールを記述する上で最も基本となる簡単なパターンから順を追っ
て説明していきます。また、この章で出現するXMLの要素はCX-ModelというSapid独自の解析方法に基づいた
要素です。CX-Modelについての詳細は5章をご覧ください。
3.1. 基本パターン(○○を使用してはならない。)
3.1.1. 指定したキーワードを違反とする
【ルール56:goto文を使用してはならない】 を例として説明していきます。
サンプルソース
1: void func(void){
2: goto LABEL;
3: LABEL:
4: }
XPathを記述する際は必ず XMLを見る必要がありますが、XMLを見る際はすべての箇所を見る必要はなく、ルー
ルに関係のある箇所に着目します。今回は “goto文を使用してはならない” というルールなので、gotoが
記述されているサンプルソース2行目の goto LABEL; 部分を見てみます。goto LABEL; 部分のXMLは下記のよ
うな構造となります。
XML
<Stmt id="s58720256">
<kw>goto</kw>
<sp></sp>
<Label>
<ident defid="s67108864">LABEL</ident>
</Label>
</Stmt>
XPathを記述する際はまずどこにチェックマーク(波線)をつけるかを考えます。今回はgoto部分にだけに
チェックマーク(波線)を付けるようにするのでgotoが XMLのどの要素のテキストノードなのかを見つける必
要があります。上記のXMLを見てみると <kw>goto</kw> と記述されていますのでgotoは<kw>のテキストノー
ドだということがわかります。ですので今回は <kw> にのみ着目します。それでは実際にXPathを記述する際
の簡単な手順をご説明します。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
14 / 35
■作成手順
1.必要な情報は<kw>要素のみなので、コンテキストノードをkwに設定します。
⇒ //kw
2.判定したいのはテキストのノードなので述語部分にテキストノードを追加します。
⇒ //kw[text()]
3.テキストノードの内容がgotoかどうかの判定処理を追加します。
⇒ //kw[text() = “goto”]
とXPathを記述すると、 “goto” と記述されている箇所すべてにチェックマークが表示されます。
この形がXPathルールを記述する際の基本となる形となります。それではこれをベースにして次は複数のキー
ワードを同時にチェックするルールの記述方法の説明を行います。
3.1.2. 指定した複数のキーワードを違反とする
【ルール122:setjmpマクロ及びlongjmp関数は使用してはならない】 を例として説明していきます。複数と
いうことで今回は2つのキーワードを違反としてチェックしていきます。
サンプルソース
1: #include <setjmp.h>
2: jmp_buf mark;
3: void func(void){
4: int var;
5: var = setjmp(mark);
6: longjmp(mark, -1);
7: }
今回は setjmp 、longjmpにチェックマークをつけますのでこの2つのキーワードに着目します。それではま
ず setjmp( Cソース5行目の var = setjmp(mark); ) の方からXMLの構造を見てみます。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
15 / 35
XML
<Stmt id="s58720300">
<Expr id="e58720300">
<ident defid="s33554772" type_id="s83886213">var</ident>
<sp></sp>
<op>=</op>
<sp></sp>
<ident defid="s33554769" type_id="s83886210">setjmp</ident>
<op>(</op>
<ident defid="s33554770" type_id="s83886343">mark</ident>
<op>)</op>
</Expr>
</Stmt>
先ほどのようにチェックしたいsetjmpがどこに書かれているかを探します。XML を見てみると setjmpは
<ident> 要素に囲まれていますので setjmpは ident要素のテキストノードだということがわかります。
setjmpが ident要素のテキストノードだということがわかったので、次にlongjmp の方のXMLを見てみます。
( サンプルソース6行目の longjmp(mark, -1); )
XML
<Stmt id="s58720305">
<Expr id="e58720305">
<ident defid="s33554767" type_id="s83886209">longjmp</ident>
<op>(</op>
<ident defid="s33554770" type_id="s83886343">mark</ident>
<op>,</op>
<sp></sp>
<Expr>
<literal defid="s75497523">-1</literal>
</Expr>
<op>)</op>
</Expr>
</Stmt>
<op>;</op>
longjmpを探してみますと、setjmp同様 longjmpも ident要素のテキストノードだということがわかります。
今回は両方とも同じ要素の(ident)のテキストノードなのでident要素にのみ着目します。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
16 / 35
■作成手順
1.両方とも<ident>タグに囲まれていますので、コンテキストノードをidentに設定します。
⇒//ident
2.次に、テキストノードの内容がsetjmpかどうかの判定処理を先に追加します。
⇒//ident[text() = “setjmp”]
3.その後 orを使用し、longjmpかどうかの判定処理も追加します。
⇒//ident[text() = “setjmp”or text() = “longjmp”]
これにより、ident要素のテキストノードの内容が “setjmp” 又は “longjmp” と記述されている箇所すべ
てにチェックマークが表示されます。
3.1.3. 指定した複数のキーワードを違反とする 2
【ルール121:<local.h>と setlocale関数は使用してはならない】 を例として説明していきます。先ほどは
同じ要素のテキストノードでしたが、今回は違う要素のテキストノードを同時にチェックをするルールの記述
方法をご説明します。
サンプルソース
1: #include <locale.h>
2:
3: void func(void){
4: setlocale( LC_CTYPE, "jpn");
5: }
今回チェックマークを付けたいのは <locale.h> setlocale の 2箇所です。ではまず <locale.h> 周辺のXML
を見てみます。
XML
<Include>
<kw>#include</kw>
<sp></sp>
<hfile id="s8388612"><locale.h></hfile>
<sp />
</Include>
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
17 / 35
■作成手順
1.<locale.h> は hfile要素 のテキストノードなので下記のように記述します。
⇒ //hfile[text()="<locale.h>")]
これで <locale.h> にチェックマークをつけることが出来るようになりました。では次に setlocale の方を
見てみます。
<Stmt id="s58720259">
<Expr id="e58720259">
<ident defid="s33554459" type_id="s83886080">setlocale</ident>
<op>(</op>
<sp></sp>
<macroCall defid="s377488738">LC_CTYPE</macroCall>
<op>,</op>
<sp></sp>
<Expr>
<literal defid="s75497473">"jpn"</literal>
</Expr>
<op>)</op>
</Expr>
</Stmt>
setlocale は ident要素のテキストノードとなっています。これまで説明してきたルールとは違い
<locale.h> setlocale の二つのキーワードはぞれぞれ別の要素(<hfile>と<ident>)のテキストノードだと
いうことがわかります。別の要素のテキストノードを同時にチェックしたい場合は、新たに別のXPathを記述
する必要があります。では setlocale をチェックするXPathを記述します。
2.まずはsetlocale が ident要素のテキストノードという式を記述します。
⇒//ident[text()="setlocale"]
ここまでで <locale.h> をチェックするXPath://hfile[text()="<locale.h>")] と setlocale をチェックす
るXPath://ident[text()="setlocale"] の 2通りが作成できました。つぎはこの2つのXPathを 1つにまとめ
る作業を行います。
3.2つのXPathをまとめる際は “ | ” を使用します。使い方は2つのXPathの間に挟むだけです。
⇒//hfile[text()="<locale.h>"] | //ident[text()="setlocale"]
これにより、別の要素のテキストノードを同時にチェックすることが出来ます。ちなみに “or”演算子を使
用しても出来そうな気がしますが、or演算子は [ ]の中(述語部分)でのみ使用可能な演算子なので使用するこ
とは出来ません。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
18 / 35
3.1.4. 指定したキーワードを含んだ箇所を違反とする
【ルール7:3文字表記は使用してはならない】 を例として説明していきます。先ほどはテキストノードの文
字が完全一致した場合を違反としてチェックするというものでしたが、今回はテキストノードに指定した文字
が含まれていれば違反としてチェックするというルールです。それにはXPath独自の関数を使用します。
サンプルソース
1: void func(void){
2: char *var0 = "test??=";
3: char *var1 = "test??(";
4: char *var2 = "test??/ ";
5: char *var3 = "test??)";
6: char *var4 = "test??'";
7: char *var5 = "??<test";
8: char *var6 = "??!test";
9: char *var7 = "??>test";
10: char *var8 = "??-test";
11:}
サンプルソース2~10行目の "test??=" 部分のXMLは下記のような構造となります。
<literal defid="s75497473">"test??="</literal>
・・・ 省略 ・・・ ※すべて同じ構造なので一部3行目~9行目は省略します。
<literal defid="s75497484">"??-test"</literal>
今回はすべてliteral要素のテキストノードなので、<literal>にのみ着目します。
■作成手順
1.まずコンテキストノードをliteralに設定します。
⇒//literal
2.特定のキーワードが含まれているかどうかを判定するには[text() = “??=”]ではなくcontainsを使用し
ます。containsの記述形式は contains(文字列1, 文字列2)です。文字列2が文字列1に含まれているかを判
定したいので下記のように記述します。
⇒//literal[ contains(text(),"??=") ]
3.or演算子を使い、残りの3文字表記の判定も同じように追加します。
⇒//literal[ contains(text(),"??=") or contains(text(),"??(") or contains(text(),"??/") or
contains(text(),"??)") or contains(text(),"??'") or contains(text(),"??<") or
contains(text(),"??!") or contains(text(),"??>") or contains(text(),"??-")]
これにより、 “??=”などの3文字表記が含まれている箇所すべてにチェックマークを表示させることが出来
ます。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
19 / 35
ここまでで、指定したキーワードを違反とするルールの記述方法を4通り学びました。では次にキーワードを
違反とする際に特定の条件を満たしたものだけ違反とするというルールの記述方法をご説明していきます。
3.2. 基本パターン + 条件
3.2.1. 特定の要素が存在した場合、指定したキーワードを違反とする。
【ルール123:<signal.h>にあるシグナル操作は使用してはならない】 を例として説明していきます。今回は
コンテキストノード以外のノードにも着目しながらXPathを記述していきます。
サンプルソース
1: #include <signal.h>
2:
3: extern void proc_sigint(void);
4:
5: void func(void){
6: signal(SIG_INT, proc_sigint);
7: }
シグナル操作を使用してはならないということなので、まずはチェックマークを付ける位置をsignalに決定
します。それでは signal の XMLを見ています。
XML
<ident defid="s33554759" type_id="s83886203">signal</ident>
signalは<ident>要素のテキストノードだということがわかります。ではXPathを記述していきます。
■作成手順
1.signalは<ident>要素のテキストノードのなので下記のように記述します。
⇒ //ident[text() = “signal” ]
ここまでは前回の節で説明した基本パターンと全く同じです。次に条件式を記述していきます。ルールに
“<signal.h>にある” という条件が書いてありますので、 <signal.h> の XMLを見てます。
XML
<hfile id="s8388610"><signal.h></hfile>
<signal.h> は<hfile>のテキストノードだということがわかります。つまり条件としては “<hfile>のテキス
トノードが <signal.h> だった場合” という条件になります。それではこの条件をXPathに記述してみます。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
20 / 35
2.先ほど作成したXPathの述語部分に<hfile>のテキストノードが<signal.h>だった場合という条件を加えま
す。条件を加えますので or ではなく and を使用します。以下の式は 「ident要素のテキストノード
が”signal”で ident要素の子ノードのhfile要素のテキストノードが”<signal.h>”」といった意味の
XPathになります。
⇒//ident[text() = “signal” and hfile[text() = “<signal.h>” ]]
これで終わりのように思えますが、まだ足りない部分があります。この式でのhfileは ident要素の子ノード
のhfile要素しか指していません。ということなのでどこの部分のhfile要素なのかを指定する必要がありま
す。ではhfile要素がどこに出現しているかを見つけます。それでは今度はXMLを全体的に見てみます。
XML
<Include>
<kw>#include</kw>
<sp></sp>
<hfile id="s8388610"><signal.h></hfile>
…省略…
<Stmt id="s58720284">
<Expr id="e58720284">
<ident defid="s33554759" type_id="s83886203">signal</ident>
<op>(</op>
…省略…
signal が出現す前に <signal.h> は出現しています。ですので <signal.h> の要素であるhfile要素は
signal の要素であるident要素より前に存在するということがわかります。ではXPathに位置を特定する処理
を追加します。
3.identより前にあるhfileという書き方は “preceding” を使用します。precedingは「先行するすべての
ノード」という意味です。
⇒//ident[ (text()="signal") and preceding::hfile[text()="<signal.h>"]]
これで“<signal.h>にある”という条件をつけることが出来ました。このXPathの意味は 「ident要素の前の、
hfileのテキストノードが<signal.h> であり、かつ ident要素のテキストがsignalだった場合」となり、
<signal.h>を includeした際にsignal関数を使用した場合はチェックマークが記述されるということになりま
す。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
21 / 35
3.2.2. 特定の要素に囲まれているノード集合を違反とする。
【ルール68:関数はいつもファイルスコープで宣言しなければならない】 を例として説明していきます。今
まではテキストノードをチェックマークを付ける対象としてきましたが、今回は複数の要素に対してチェック
マークをつけるという方法をご説明します。
サンプルソース
1: #include <stdio.h>
2:
3: void func1();
4:
5: void func1(void){
6: void func2 (void) ;
7: }
8:
9: void func2(void){
10: printf("hello world");
11: }
今回チェックマークをつけるのは関数のプロトタイプ宣言部分とします。違反箇所は6行目のvoid
func2(void)になりますのでvoid func2(void)箇所にチェックマークが付くようにXPathを考える必要があり
ます。XMLの構造は下記の通りです。
<Prototype defid="s33555003">
<Type>
<kw sort="type">void</kw>
</Type>
<sp></sp>
<ident defid="s33555003" type_id="s83886422">func2</ident>
<op>(</op>
<Type>
<kw sort="type">void</kw>
</Type>
<op>)</op>
</Prototype>
今までのルールとは異なり今回は、チェックマーク(波線)を付ける箇所が複数の要素に分かれているのがわ
かります。そこでまずは複数の要素が共通で持っているノードを探します。共通のノードは<Prototype
defid="s33555003">、つまりこれらのノードの親ノードです。ですので今回はこのノードに着目します。
Prototype要素はプロトタイプ宣言全体に付けられる要素です。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
22 / 35
■作成手順
1.チェックマーク(波線)を付けたい箇所は<Prototype defid="s33555003">に囲まれている要素全体(子ノー
ド)なのでまずは下記のように記述します。
⇒//Prototype
2.しかし、これだけではプロトタイプ宣言すべてにチェックマーク(波線)を付けてしまうことになるので条件
を指定する必要があります。ルールを見てみると 「関数はいつもファイルスコープで宣言しなければならな
い」なので、「関数の中で関数を宣言してはならない」と言い換えて考えることとします。では、違反してい
るプロトタイプ宣言と、違反していないプロトタイプ宣言の違いをXMLから見てみます。
違反しているプロトタイプ宣言
<Function id="s33555002">
・・・省略・・・
<Prototype defid="s33555003">
<Type>
<kw sort="type">void</kw>
</Type>
<sp></sp>
<ident defid="s33555003" type_id="s83886422">func2</ident>
<op>(</op>
<Type>
<kw sort="type">void</kw>
</Type>
<op>)</op>
</Prototype>
・・・省略・・・
</function>
違反していないプロトタイプ宣言
<Prototype defid="s33555002">
<Type>
<kw sort="type">void</kw>
</Type>
<sp></sp>
<ident defid="s33555002" type_id="s83886420">func1</ident>
<op>(</op>
<op>)</op>
</Prototype>
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
23 / 35
違反しているプロトタイプ宣言の祖先ノードにFunction要素が存在することがわかります。一方違反してい
ないプロトタイプ宣言は祖先ノードにFunction要素がありません。ですので祖先ノードにFunction要素が存
在するPrototype要素のみをチェックすればよいということがわかります。それをXPathに記述すると下記の
ような形になります。
⇒//Prototype[ancestor::Function]
ancestorは祖先ノードを指定するのでこのXPathの意味は「Prototype要素[祖先ノードにFunctionが存在す
る]」つまりチェックさせるのは「祖先ノードにFunction要素が存在するPrototype要素」となり、関数内の
プロトタイプ宣言にのみ警告マークを表示させることが出来ます。このようにチェック出来る対象はテキスト
ノードだけではありません。仮に「//ident」 といったXPathを下記チェックを行うとident要素すべてに
チェックマークが表示されるようになります。
3.2.3. 特定の要素に囲まれているノード集合を違反とする2
【ルール35:ブーリアン値を返す式の中で代入演算子が使用されてはならない】を例として説明していきます。
今回は属性値を使用してXPathを記述します。またここでは、「ブーリアン値を返す式」はifの条件式の中、
代入演算子は “ = ”のみとして考えていきます。
サンプルソース
1: void func(void){
2: int var;
3: if(var = 10){
4: var = 20;
5: }
6: }
今回チェックしたいのはif文の条件式である = だけで = はチェックしないようにします。また、今回は =
の親ノードを順にたどっていくという方法で考えます。それではまず if文の条件式の部分がどうなっている
かをXMLから読み取っていきます。(if(var = 10) 部分のXML)
XML
<Stmt sort="If" id="s50331650">
<kw sort="Stmt">if</kw>
<op>(</op>
<Expr id="e58720258">
<ident defid="s33554433" type_id="s83886082">var</ident>
<sp></sp>
<op>=</op>
<sp></sp>
<Expr>
<literal defid="s75497472">10</literal>
</Expr>
</Expr>
<op>)</op>
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
24 / 35
…省略…
■作成手順
1.いつものようにテキストノードが “ = ”かどうかの判定をまず記述します。
⇒ //op[text() = “=” ]
次にifの条件文だという指定を行っていきます。XMLを見るとifと記述されているのは2箇所あります。1つ
目は<Stmt sort="If" id="s50331650">、2つ目は<kw sort="Stmt">if</kw> になります。どちらを使っても記
述することができますが、より指定しやすいほうを選びます。まず <Stmt sort="If" id="s50331650"> から
見てみると、現在のコンテキストノード( //op[text() = “=” ] ) は opなのでそこから見ると <Stmt
sort="If" id="s50331650"> は祖先ノードにあたります。一方 <kw sort="Stmt">if</kw> に関しては親ノー
ドの先行する兄弟ノードにあたります。なのでop要素とわかりやすい関係である <Stmt sort="If"
id="s50331650"> を使用することとします。
2.<Stmt sort="If" id="s50331650"> を見るには親ノードを経由する必要があるので下記のように記述します。
この場合親ノードはExpr要素なのでそのように記述します。
⇒ //Expr/op[text() = “=” ]
今の段階では「Expr要素の子ノードであるop要素が = だったらチェックを行う」という形になります。それ
ではもう一段階ノードを掘り下げています。
3.Expr要素はStmt要素の子ノードなのでそのように記述します。
⇒ //Stmt/Expr/op[text() = “=” ]
この段階では「Stmt要素の子ノードがExpr要素で、そのExpr要素の子ノードであるop要素が = だったら
チェックを行う」という形になっています。今のままではまだif文の条件式なのかをXPathから判断すること
は出来ません。そこでStmt要素の属性である sort= “if” を利用します。つまりStmt要素の属性である
sortの属性値が if だった場合と考えるわけです。それでは実際にXPathを書いてみます。
4.@ を使用し属性値の判定を行う。
⇒ //Stmt[@sort="If"]/Expr/op[ text()="=" ]]
これにより「属性@sortの属性値がifであるStmt要素の、子ノードがExprで、そのExpr要素の子ノードであ
るop要素が = だったらチェックを行う」といった形になり、if文の条件式ないの = にチェックマークをつ
けることができます。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
25 / 35
3.3. まとめ
以上で何通りのルールをご紹介しましたが、 基本のパターンは //ident[text() = “goto”]のような形です。
このパターンに条件などを加えるだけで記述できるルールの種類も広がると思います。ここではテキストノー
ドをチェックするルールを中心にご紹介しましたが、要素の数を数えたり、出現位置を特定したりすることも
出来ます。
■Xpathルール作成のコツ
1. チェックする場所(波線を付ける箇所)を決定する。
2. 条件は後で記述する。
3. Xpathを記述する際は常に現在の式はどこのノードを指しているのかを把握しておく。
4. XMLと照らし合わせながら記述する。
5. Xpathの文法に違反していないかを確認する。
Xpathルールを作成する際はCX-Checkerの機能の1つであるXPathViewerを使用すると便利です。
XPathViewerについてはcx-checker-user-manual.pdfを参考にしてください。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
26 / 35
4. XPathルール実装方法
第 4章で作成したXPathを実装する方法をご説明します。
ルールを実装するには専用のテプレートを使用します。下記がそのテンプレートとなります。
Xpathルールテンプレート(XMLファイル)
<rules>
<oneRule>
<level> 1~5 </level>
<content> ルール説明 </content>
<xpath> ~XPath~ </xpath>
<condition>prohibit</condition>
</oneRule>
</rules>
rules ルールのルート要素
oneRule ひとつのXPathルールを表す要素。複数存在させることが可能で<oneRule>を増やすことによって
複数のXPathを記述することが可能です。
level ルールの重要度を表す要素。Misraのルールでも「推奨」、「必要」といったルールの重要度があ
るように、CX-checkerでもルールの重要度を指定することが可能です。重要度の範囲は1 ~ 5
までとなります。
content ルールの説明を表す要素。Eclipseで警告マークが表示されたときに表示されるメッセージです
xpath Xpathを記述する要素。ここに第 4章で作成したようなXPathを記述します。
※XMLは<>で一つのタグとするためXPathに< や > を直接記述することが出来ません。その際は
文字参照を使用して記述してください。代表的な文字参照( <, < >, > &,&)
condition XPathで指定した要素が、require なら要素が見つからないと違反、prohibit なら要素が見つか
ると違反となります。
※基本的にはprohibitを使用します。
例:【ルール56:goto文を使用してはならない】 を実装すると下記のような形になります。
<rules>
<oneRule>
<level> 5 </level>
<content> misra-56 </content>
<xpath>//kw[text() = “goto”]</xpath>
<condition>prohibit</condition>
</oneRule>
</rules>
必要ルールなので 5にします
56番のルールなのでこのように指定します
第 4章で作成した XPa t h を記述します
g o t o が見つかった場合なので conditionにします
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
27 / 35
5. CX-Checkerのノード
本項目ではCX-Checkerでルールを記述する際に使用するノードを記述します。
5.1. CX-model
CX-modelとはSapid使用するC言語ソースの構文要素を抽象化したモデルです。
Sapidがソースコードの解析を行い出力するXMLファイルはCX-modelに従い出力されます。
CX-modelは大別して17の終端要素と14の非終端要素に分けられ、以下の特徴があります。
・終端要素…子ノードにテキストノードのみを持つ字句情報。テキストにはソースコードの断片が記述される。
・非終端要素…子ノードに他ノードを持つ構文情報。テキストノードを持たない。
以下に終端要素、非終端要素、属性の一覧を記述します。
表3-1
終端要素
終端要素名 意味 属性
File ソースプログラムのファイルを表す @id
Define マクロ定義を表す
Include include文を表す
Function 関数定義を表す @id
Global グローバル変数宣言を表す @id, @defid
Local ローカル変数を表す @id, @defid
Argument 仮引数宣言を表す @id
Typedecl typedef宣言を表す @id
Prototype プロトタイプ宣言を表す @defid
Param 関数定義の括弧内のカンマ(',')で区切られた
1つ1つを表す
@id
Type 型を表す
Tag タグを表す @id
Member メンバ変数を表す @id
Enum 列挙子を表す @id
Stmt 文を表す @sort
Expr 式を表す
Label ラベルを表す
非終端要素
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
28 / 35
非終端要素名 意味 属性
hfile ヘッダファイルを表す @id, @ref
macroPattern マクロ名を表す @id
macroBody マクロ本体を表す
macroCall マクロ呼び出しを表す @defid
ident 識別子を表す @defid, @sort
literal リテラルを表す @defid
comment コメントを表す
op 演算子を表す
pp プリプロセッサで展開される部分を表す
no_expand プリプロセッサで展開されない部分を表す
sp 空白文字を表す @sort @length
nl 改行文字を表す @line, @offset
kw キーワードを表す @sort
T offsetずれによりできてしまうテキストを暫
定的に表す
CX-modelの属性
属性名 型 意味
id ID 識別番号
defid CDATA 定義の識別番号
line CDATA 行番号
offset CDATA オフセット
sort CDATA それぞれの要素におけるカテゴリ
ref CDATA 参照したヘッダファイルの識別番号
length CDATA 空白文字の長さ
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
29 / 35
6. CX-model要素詳細
6.1. File
ソースプログラムのファイルを表す。この要素はCX-model XML文書のルートノードとなる。
Child nodes:
/Define, /Include, /Function, /Prototype, /Global, /Typedecl, /Tag
/comment, /pp, /no_expand, /macroCall, /op, /sp, /nl
6.2. Define
マクロ定義を表す。”#define”からあ改行まで。
Child nodes:
/kw, /macroPattern, /macroBody, /sp, /comment
6.3. Include
include文を表す。”#inckude”から”゛(ダブルクォーテーション)”もしくは”>”まで。
Child nodes:
/kw, /hfile, /sp, /comment
6.4. Function
関数定義を表す。
Child nodes:
/Define, /Type, /Typedef, /Tag, /Param, /Argument, /Local, /Global, /Stmt, /Prototype, /Expr,
/macroCall, /Label, /ident, /comment, /literal, /pp, /no_expand, /kw, /sp, /op, /nl,
@id
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
30 / 35
6.5. Global
グローバル宣言を表す。
Child nodes:
/Type, /ident, /Enum, /Global, /Member, /Stmt, /Include,
/literal, /macroCall, /kw, /sp, /op, /nl, /comment,
@id, @defid
6.6. Local
ローカル変数宣言を表す。
Child nodes:
/Type, /Stmt, /Enum,
/ident, /literal, /macroCall, /kw, /sp, /op, /nl, /comment,
@id, @defid
6.7. Argument
仮引数宣言を表す。
Child nodes:
/Type, /Param,
/macroCall, /ident, /kw, /sp, /op, /nl, /comment,
@id
6.8. Typedecl
typedef宣言を表す。
Child nodes:
/Typedecl, /Member, /Enum, /Type, /ident, /Define,
/macroCall, /literal, / kw, /sp, /pp, /no_expand, /op, /nl, /comment,
@id
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
31 / 35
6.9. Prototype
プロトタイプ宣言を表す。
Child nodes:
/Type, /Param, /Argument,
/ident, /macroCall, /literal, /comment, /pp, /no_expand, /kw, /sp, /op, /nl,
@defid
6.10. Param
関数定義の括弧内のカンマ(',')で区切られた1つ1つを表す。
Child nodes:
/Type,
/ident, /kw, /sp, /op, /nl, /comment, /macroCall, /literal,
@id
6.11. Type
型を表す。
Child nodes:
/ident, /kw, /op, /nl, /comment
6.12. Tag
タグを表す。(structから'}'まで)
Child nodes:
/Enum, /Define, /Member, /Expr,
/ident, /literal, /pp, /no_expand, /kw, /sp, /op, /nl, /comment,
@id
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
32 / 35
6.13. Member
メンバ変数を表す。
Child nodes:
/Tag, /Type, /Member, /Enum, /Define, /Expr,
/no_expand, /pp, /macroCall, /ident, /literal, /kw, /sp, /op, /nl, /comment,
@id
6.14. Enum
列挙子を表す。
Child nodes:
/Type, /Expr, /macroCall, /ident,
/literal, /kw, /sp, /op, /nl, /comment
@id
6.15. Stmt
文を表す。'{'と'}'で囲まれたブロック, fi, else, while, for, switch, do-whileブロック, ';'までの式
Child nodes:
/Stmt, /Expr, /Local, /Define,
/macroCall, /literal, /Label, /pp, /no_expand, /kw, /sp, /op, /nl, /comment,
@sort
6.16. Expr
式を表す。
Child nodes:
/Expr, /Type, /Label,
/macroCall, /literal, /ident, /kw, /sp, /op, /nl, /comment, /pp, /no_expand
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
33 / 35
6.17. Label
ラベルを表す。
Child nodes:
/Stmt,
/kw, /sp, /literal, /ident, /macroCall
6.18. hfile
ヘッダファイルを表す。
Child nodes:
@id, @ref
6.19. macroPattern
マクロ名を表す。
Child nodes:
@id
6.20. macroBody
マクロ本体を表す。
6.21. macroCall
マクロ呼び出しを表す。
Child nodes:
@defid
6.22. ident
識別子を表す。
タイトル
XPath記述マニュアル
日付
2010/09/27
ページ数
34 / 35
Child nodes:
@defid, @sort
6.23. literal
リテラルを表す。
Child nodes:
@defid
6.24. comment
コメントわ表す。
6.25. op
演算子を表す。
6.26. pp
プリプロセッサで展開される部分を表す。
6.27. no_expand
プリプロセッサで展開されない部分を表す。
6.28. sp
空白文字を表す。
Child nodes:
@sort, @length