DelphiのTXMLDocumentを使って名前空間に属するタグを検索する

元ネタは「Delphi XE Pro - XMLファイルの値取得がわからない : arigayas の 雑記帳」より。

TXMLDocumentで名前空間に属するタグを検索するには、IXMLNodeList.FindNodeの2番目の引数に名前空間を指定します。

XMLNode := XMLDocument.DocumentElement.ChildNodes.FindNode(NodeName, NamespaceURI);

次のコードでは、下のようなXMLファイルからem:nameの値を取得します。

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="略">
    <Description>
        <em:description>ソフト説明</em:description>
        <em:name>テスト</em:name>
        <em:version>0.0.1</em:version>
    </Description>
</RDF>

XMLファイルからem:nameの値を取得するコード

procedure TForm1.Button1Click(Sender: TObject);
const
  FileName: string = 'C:\test\test.xml'; //XMLファイルのファイル名
  NamespaceURI: string = '略'; // 検索するノードの名前空間(xmlns:emの値)
  NodeName: string = 'name'; // 検索するノードの名前
var
  XMLDocument: IXMLDocument;
  XMLNode: IXMLNode;
begin
  XMLDocument := LoadXMLDocument(FileName);
  XMLNode := XMLDocument.DocumentElement.ChildNodes[0].ChildNodes.FindNode
    (NodeName, NamespaceURI);
  Memo1.Lines.Add(XMLNode.NodeValue);
end;

別解として、全てのノードを探索するコード

procedure TForm1.Button2Click(Sender: TObject);
const
  FileName: string = 'C:\test\test.xml'; //XMLファイルのファイル名
var
  XMLDocument: IXMLDocument;
begin
  XMLDocument := LoadXMLDocument(FileName);
  WriteAllNode(XMLDocument.DocumentElement);
end;

procedure TForm1.WriteAllNode(XMLNode: IXMLNode; Indent: string);
const
  NodeName: string = 'em:name'; // 検索するノードの名前
var
  I: Integer;
begin
  if (XMLNode.NodeType = ntText) then
  begin
    Memo1.Lines.Add(Format('%s%s', [Indent, XMLNode.NodeValue]));
    if (XMLNode.ParentNode.NodeName = NodeName) then
      Memo1.Lines.Add('★見つかりました。');
  end
  else
  begin
    Memo1.Lines.Add(Format('%s%s', [Indent, XMLNode.NodeName]));
  end;

  for I := 0 to XMLNode.ChildNodes.Count - 1 do
  begin
    WriteAllNode(XMLNode.ChildNodes.Nodes[I], Indent + ' ');
  end;
end;

PHPで指定したディレクトリのファイルの一覧を取得する

PHP5で導入されたDirectoryIteratorを使って、特定のディレクトリに含まれているファイル一覧を取得するコードです。
サブディレクトリのファイルを取得する方法も紹介します。

ディレクトリのファイルの一覧を取得する

//処理したいディレクトリのパス
$path = dirname(__FILE__);

$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
    echo $file, PHP_EOL;
}

ディレクトリやファイルのパスとファイル名を取得する

パスとファイル名を取得するにはgetPathname()メソッドを使用します。

//処理したいディレクトリのパス
$path = dirname(__FILE__);

$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
    echo $file->getPathname(), PHP_EOL;
}

‘.’ もしくは ‘..’を判定する

上のコードでは、’.’や’..’も含まれます。

‘.’や’..’を判定するにはisDot()メソッドを使用します。

//処理したいディレクトリのパス
$path = dirname(__FILE__);

$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
    //'.'と'..'は表示しない
    if (!$file->isDot()) 
        echo $file, PHP_EOL;
}

ファイルとディレクトリを判定する

ファイルかどうかを調べるにはisFile()メソッド、ディレクトリかどうかを調べるにはisDir()メソッドを使用します。

//処理したいディレクトリのパス
$path = dirname(__FILE__);

$dir = new DirectoryIterator($path);
foreach ($dir as $file) {
    if ($file->isDot()) //'.'と'..'は表示しない
        continue;

    if ($file->isFile()) //ファイルの時
        echo $file, ' is File', PHP_EOL;

    if ($file->isDir()) //ディレクトリの時
        echo $file, ' is Dir', PHP_EOL;
}

サブディレクトリを含めたすべてのファイルを表示する

サブディレクトリを含めたすべてのファイルを表示するサンプルプログラムです。

/**
 * 指定したディレクトリとそのサブディレクトリのファイルを表示する
 * @param string $path ディレクトリのパス
 */
function showFiles($path) {
    $dir = new DirectoryIterator($path);
    $dirs = array();
    foreach ($dir as $file) {
        if ($file->isDot()) //'.'と'..'は表示しない
            continue;
        if ($file->isDir())
            $dirs[] = $file->getPathname();
        if ($file->isFile())
            echo $file->getPathname(), PHP_EOL;
    }
    //サブディレクトリのファイルを表示する
    foreach ($dirs as $dir) {
        showFiles($dir);
    }
}

//処理したいディレクトリのパス
$path = dirname(__FILE__);

//指定したディレクトリとそのサブディレクトリのファイルを表示する
showFiles($path);

PHP 5.2から導入されたfilter_var関数で入力された値を検証する

filter_var関数

PHP 5.2.0からfilter_var関数を使って値を簡単に検証できるようになりました。

メールアドレスの検証や、数値の範囲チェックなどの処理を一貫した書き方で記述できます。

filter_var関数の使用例を紹介します。

mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )

filter_var関数の最初の引数に検証する値、2番目の引数に検証方法を指定します。
2番目の引数に使用できる検証方法は「マニュアルの検証フィルタ」にまとまっています。

メールアドレスが正しいかどうかを検証する

$var = 'bob@example.com'; //検証するメールアドレス
if (filter_var($var, FILTER_VALIDATE_EMAIL) === false) {
  echo('メールアドレスが不正です。');
}

入力された値が整数かどうかを検証する

$var = '123'; //検証する値
if (filter_var($var, FILTER_VALIDATE_INT) === false) {
  echo('入力された値は整数ではありません');
}

入力された整数の範囲を検証する

filter_var関数の3番目の引数で範囲を指定します。

$var = '99'; //検証する値

$range = array(//検証する範囲
    'min_range'=>10, //最小値
    'max_range'=>20  //最大値
    ); 

if (filter_var($var, FILTER_VALIDATE_INT, array('options'=>$range)) === false) {
  echo('入力された値は範囲内の整数ではありません');
}

検証に失敗したときに返す値を指定できます。

$var = '99'; //検証する値
$options = array(
    'min_range' => 10, //最小値
    'max_range' => 20, //最大値
    'default' => 0 //検証に失敗したときに返す値
);
var_dump(filter_var($var, FILTER_VALIDATE_INT, array('options' => $options))); //=>0

複数の値をまとめて検証する

複数の値をまとめて検証するときはfilter_var_array関数を使用します。

//検証する値
$data = array(
    'email' => 'bob@@example.com',
    'age' => 120,
);
//検証方法
$args = array(
    //emlはメールアドレスがどうかを検証する
    'email' => FILTER_VALIDATE_EMAIL,
    //ageは18以上99以下の整数かどうかを検証する
    'age' => array(
        'filter' => FILTER_VALIDATE_INT,
        'options' => array(
            'min_range' => 18, //最小値
            'max_range' => 99, //最大値
        )
    )
);
var_dump(filter_var_array($data, $args));

実行結果

array (size=2)
  'email' => boolean false
  'age' => boolean false

Memoコンポーネントの行をスクロールする

Memoコンポーネントの行をスクロールする

//下に1行スクロールする
Memo1.Perform(EM_LINESCROLL, 0, 1);

//下に10行スクロールする
Memo1.Perform(EM_LINESCROLL, 0, 10);

//上に1行スクロールする
Memo1.Perform(EM_LINESCROLL, 0, -1);

//一番下までスクロールする
Memo1.Perform(EM_LINESCROLL, 0, Memo1.Lines.Count);

サンプルプログラム

memo01

procedure TForm1.Button1Click(Sender: TObject);
begin
  //下に1行スクロール
  Memo1.Perform(EM_LINESCROLL, 0, 1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  //下に10行スクロール
  Memo1.Perform(EM_LINESCROLL, 0, 10);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  //上に1行スクロール
  Memo1.Perform(EM_LINESCROLL, 0, -1);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  //一番下までスクロール
  Memo1.Perform(EM_LINESCROLL, 0, Memo1.Lines.Count);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  Memo1.Lines.Clear;
  for I := 1 to 999 do
    Memo1.Lines.Add(IntToStr(I));
end;

関連