研究開発

「はじめてのVectorScript」と題して連載を始めるわけですが、本連載は「Vectorworksは持っているけどVectorScriptって何?」、「プログラミングって難しいんでしょ?」「アイデアはあるんだけど...」という人が「それ、VectorScriptでやれば簡単だよね」と言えるくらいになるのが目標です。

VectorworksはMacintosh版とWindows版とのマルチプラットホーム環境でありながらも、VectorScriptはOSを意識することのなくプログラミングが可能で、どちらでプログラミングしてもソースコードの変更なしでMacintosh、Windowsどちらでも実行が可能です。そしてVectorworksを持っていればいますぐにでも始められます。

ゲーム機の場合、DQ7(ソフト)で遊びたいという理由で3DS(ハード)を選ぶと思います。「このソフト(あなたが書いたスクリプト)を使いたいためにVectorworksを選びました」と言わせるようなプログラムを目指してがんばりましょう。自分のアイデアをプログラム化しブログで公開なんてことも夢ではありません。

第9章 XML

VectorScriptにはXMLパーサとしてXML関数が用意されています。
それらを使う事により、XMLファイルへのアクセスが可能になります。
通常のファイルI/Oに比べて、ランダムにアクセスできDBのように便利に扱う事が可能です。

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Canon>
  <Printer date="2015-09-03" name="PIXUS MG7730F"/>
    <date>2015-09-03</date>
    <name>PIXUS MG7730F</name>
  </Printer>

  <Camera date="2015-04-17" name="EOS Kiss X8i"/>
    <date>2015-04-17</date>
    <name>EOS Kiss X8i</name>
  </Camera>
</Canon>
のようなXMLで書かれているファイルを読み取り、書き込み、変更、削除ができます。

・初期化と内部メモリの解放
 XML関数を使う場合には、XMLのシステムを最初に初期化する必要があります。
 初期化のために、

InitXML : LONGINT;

を使います。

 また終了時にはメモリを解放するために、

ReleaseXML( XMLHandle : LONGINT ) : INTEGER;

を使います。
 XML関数は初期化時に得た値を引数として渡す必要がありますのでとっておく必要があります。
PROCEDURE Example901;
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
BEGIN
	xmlH := InitXML;

	{この間に処理を書く}

	checkcode := ReleaseXML( xmlH );
END;
Run( Example901 );

・ファイルの読み込み
 ファイルからデータを読み込むには以下の手順で行います。

 1.ファイルを開く

 ファイルを開くには、

ReadXMLFile( XMLHandle : LONGINT; whichPath : INTEGER; filename : STRING ) : INTEGER;

を使います。whichPathはVectorworksが指定するフォルダ番号です。GetFolderPathにフォルダ番号リストが載っています。
PROCEDURE Example902;
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, 'sample.xml' );

	checkcode := ReleaseXML( xmlH );
END;
Run( Example902 );
XMLデータの場所が任意の場合には、ユーザにファイルの位置を選択してもらうために、

GetFileN( title, defaultFolder, mask : STRING; VAR fileName : STRING ) : BOOLEAN;

を使います。この文字列引数はユーザの選んだファイルのある場所のパスを返してくれます。
PROCEDURE Example903;
LABEL
	9999;
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;
	boo := GetFileN( '', '', 'xml', fileName );
	IF NOT boo THEN
	BEGIN
		GOTO 9999;
	END;
	checkcode := ReadXMLFile( xmlH, -1, fileName );

	checkcode := ReleaseXML( xmlH );

9999:
END;
Run( Example903 );

 2.データを読み込む

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Canon>
  <Printer>
    <name>PIXUS MG7730F</name>
  </Printer>
</Canon>
要素データの読み込みには、

GetElementValue( XMLHandle : LONGINT; elementPath : STRING; VAR value : STRING ) : INTEGER;

を使います。
PROCEDURE Example904;
LABEL
	9999;
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, elementPath, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;
	boo := GetFileN( '', '', 'xml', fileName );
	IF NOT boo THEN
	BEGIN
		GOTO 9999;
	END;
	checkcode := ReadXMLFile( xmlH, -1, fileName );
	elementPath := '/Canon/Printer/name';
	checkcode := GetElementValue( xmlH, elementPath, value );

	checkcode := ReleaseXML( xmlH );

9999:
END;
Run( Example904 );

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Canon>
  <Printer date="2015-09-03" name="PIXUS MG7730F"/>
</Canon>
属性の値の読み込みには、

GetAttributeValue( XMLHandle : LONGINT; elementPath, attribute : STRING; VAR value : STRING ) : INTEGER;

を使います。
PROCEDURE Example905;
LABEL
	9999;
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, elementPath, attribute, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;
	boo := GetFileN( '', '', 'xml', fileName );
	IF NOT boo THEN
	BEGIN
		GOTO 9999;
	END;

	checkcode := ReadXMLFile( xmlH, -1, fileName );
	elementPath := '/Canon/Printer';
	attribute := 'name';
	checkcode := GetAttributeValue( xmlH, elementPath, attribute, value );

	checkcode := ReleaseXML( xmlH );

9999:
END;
Run( Example905 );

・ファイルの書き込み
 ファイルにデータを書き込むには以下の手順で行います。

 1.ファイルの確認

 書き込む場合のファイルのオープンも取り込む場合と同じです。ただしファイルがない場合、

CreateNewXMLDocument( XMLHandle : LONGINT; rootElementName : STRING ) : INTEGER;

を実行してファイルの初期化を行います。

 また書き込みを反映させるにはかならず

WriteXMLFile( XMLHandle : LONGINT ) : INTEGER;

を実行します。
PROCEDURE Example906;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	rootElementName : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'sample';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example906 );

 2.データを書き込む

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Canon>
  <Printer>
    <name>PIXUS MG7730F</name>
  </Printer>
</Canon>
要素データの書き込みには、

SetElementValue( XMLHandle : LONGINT; elementPath : DYNARRAY[] of CHAR; value : DYNARRAY[] of CHAR ) : INTEGER;

を使います。
PROCEDURE Example907;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'Canon';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/Canon/Printer/name';
	value := 'PIXUS MG7730';
	checkcode := SetElementValue( xmlH, elementPath, value );

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example907 );

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Canon>
  <Printer date="2015-09-03" name="PIXUS MG7730F"/>
</Canon>
属性の値の書き込みには、

SetAttributeValue( XMLHandle : LONGINT; elementPath : DYNARRAY[] of CHAR; attribute : DYNARRAY[] of CHAR; value : DYNARRAY[] of CHAR ) : INTEGER;

を使います。
PROCEDURE Example908;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath, attribute, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'Canon';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/Canon/Printer';
	attribute := 'date';
	value := '2015-09-03';
	checkcode := SetAttributeValue( xmlH, elementPath, attribute, value );

	attribute := 'name';
	value := 'PIXUS MG7730';
	checkcode := SetAttributeValue( xmlH, elementPath, attribute, value );

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example908 );

要素データ、属性の値の変更は、同じ名称のタグで書き込めば変更(更新)されます。

要素データの削除には、

DeleteElement( XMLHandle : LONGINT; elementPath : DYNARRAY[] of CHAR ) : INTEGER;

を使います。
PROCEDURE Example909;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'Canon';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/Canon/Printer/name';
	checkcode := DeleteElement( xmlH, elementPath );

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example909 );

属性の値の削除には、

DeleteAttribute( XMLHandle : LONGINT; elementPath : DYNARRAY[] of CHAR; attribute : DYNARRAY[] of CHAR ) : INTEGER;

を使います。
PROCEDURE Example910;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath, attribute : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'Canon';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/Canon/Printer';
	attribute := 'date';
	checkcode := DeleteAttribute( xmlH, elementPath, attribute );

	attribute := 'name';
	checkcode := DeleteAttribute( xmlH, elementPath, attribute );

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example910 );


<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<CANON>

  <PRINTER プリンタ名="PIXUS MG7730">
    <ink>BCI-350</ink>
    <ink>BCI-351</ink>
  </PRINTER>

  <PRINTER プリンタ名="PIXUS XK80">
    <ink>XKI-N10</ink>
    <ink>XKI-N11</ink>
  </PRINTER>

</CANON>
要素や、属性が複数ある場合の読み込みは、配列データとして扱われるため[]を付けます。
PROCEDURE Example911;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath, attribute, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'CANON';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/CANON/PRINTER[1]';
	attribute := 'プリンタ名';
	checkcode := GetAttributeValue( xmlH, elementPath, attribute, value );

	elementPath := '/CANON/PRINTER[2]/ink[2]';
	checkcode := GetElementValue( xmlH, elementPath, value );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example911 );

要素や、属性が複数ある場合の書き込みは、配列データとして扱われるため[]を付けます。
PROCEDURE Example912;
CONST
	PXML = 'Sample.xml';
VAR
	xmlH : LONGINT;
	checkcode : INTEGER;
	fileName, rootElementName, elementPath, attribute, value : STRING;
	boo : BOOLEAN;
BEGIN
	xmlH := InitXML;

	checkcode := ReadXMLFile( xmlH, 15, PXML );

	IF checkcode < 0 THEN
	BEGIN
		rootElementName := 'CANON';
		checkcode := CreateNewXMLDocument( xmlH, rootElementName );
	END;

	elementPath := '/CANON/PRINTER[1]/ink[3]';
	value := 'BCI-370';
	checkcode := SetElementValue( xmlH, elementPath, value );

	elementPath := '/CANON/PRINTER[1]/ink[4]';
	value := 'BCI-371';
	checkcode := SetElementValue( xmlH, elementPath, value );

	checkcode := WriteXMLFile( xmlH, 15, PXML );

	checkcode := ReleaseXML( xmlH );

END;
Run( Example912 );

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<CANON>

  <PRINTER プリンタ名="PIXUS MG7730">
    <ink>BCI-350</ink>
    <ink>BCI-351</ink>
    <ink>BCI-370</ink>
    <ink>BCI-371</ink>
  </PRINTER>

  <PRINTER プリンタ名="PIXUS XK80">
    <ink>XKI-N10</ink>
    <ink>XKI-N11</ink>
  </PRINTER>

</CANON>

VectorScriptに関するお問い合わせ

VectorScriptに関するお問合せは、以下からお問い合せください。

エーアンドエー株式会社 研究開発室

email:develop@aanda.co.jp