7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[PHP]SimpleXMLとエスケープ

Last updated at Posted at 2016-09-04

はじめに

PHPのSimpleXMLの動きがわりと不可思議なのでまとめです。

テキストノードのエスケープ

SimpleXMLでテキスト入れるには大体3つくらいのやり方があります。

$xml = new SimpleXMLElement('<root></root>');

$text = '"PHP&XML!"\(>_@)/';
/*1つめ*/
$item1 = $xml->addChild('item1');
$item1[0] = $text;
$this->assertEquals($text,$item1[0]);

/*2つめ*/
$text2 = $xml->addChild('item2')->{0} = $text;
$this->assertEquals($text,$xml->item2[0]);

/*3つめ*/
$item3 = $xml->addChild('item3',$text);
$this->assertEquals($text,$item3[0]);

このうち3つ目はアサートが通りません。
addChildの第二引数でテキストを入れた場合、
アンパサンドがなぜかエスケープしてくれません。不思議です。

2つ目は一行でエレメントの作成とテキストの入力ができて便利ですが、
返り値が当然SimpleXMLElementでなくテキストになるので注意です。

$item[0]で入力して、$item[0]で出力するのが安定です。

属性のエスケープ

属性の入力は二通りあります。

$xml = new SimpleXMLElement('<root></root>');

$text = '"PHP&XML!"\(>_@)/';

/*1つめ*/
$item1 = $xml->addChild('item1');
$item1->addAttribute('attr1',$text);
$this->assertEquals($text,$item1['attr1']);

/*2つめ*/
$item2 = $xml->addChild('item2');
$item2['attr2'] = $text;
$this->assertEquals($text,$item2['attr2']);

addChildの挙動を考えるとaddAttributeもエスケープに失敗しそうですが、
こちらは両方ともキチンとエスケープしてくれ、SimpleXMLに触れる人間を混乱に陥れます。

XPathのエスケープ

存在しません。
関数が用意されてないので正規表現頑張ろう死のうってレベルではないです。
SimpleXMLのXPathは1.0なのでエスケープのまともな定義自体が存在していません。

次のようなコードを書くといずれ死にます。

$target = current($xml->xpath('./haystack/book[title/text()="' . $needle. '"]'));

foreachで地道に探索しましょう。

$target = null;
foreach($xml->xpath('./haystack/book') as $book){
 if ($book->title[0] === $needle){
   $target = $book;
   break;
 }
}

終わりに

ちなみにエレメントや属性は次のようにunsetで削除できます。

$target = $xml->item1;

/*属性の削除*/
unset($target['attr1']);

/*エレメントの削除*/
unset($target[0]);

$input[0] = $textのことなどを合わせて考えると、
SimpleXMLにはXMLを配列的に扱いたい的な雰囲気があります。

7
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?