SimpleXMLで名前空間付きタグの一覧を取得する
via. http://d.hatena.ne.jp/kakku22/20080914/1221366973
まず,SimpleXMLで読み込めなかった状況のみを載せておく.
下のように,普通に出来ると思いきや,何も出力されなかったので,諦めたって話w
<?php $xml = simplexml_load_file("./onto.owl"); print_r($xml);XMLReaderを使ってオントロジーのクラス数を数える(XMLReader初体験!) - kakakakakku blog
実際は、
<?php $xml = simplexml_load_file("./onto.owl"); var_dump($xml);
の結果は、
object(SimpleXMLElement)#1 (0) { }
となります。実は、XML自体はSimpleXMLElementとして読み込まれているのですが、アクセスは普通にはできないのです。なぜなら名前空間がバッチリついているからですね。
というわけで、名前空間付きのタグを取り出す方法の復習。
SimpleXMLで名前空間付き要素を取り出す
<?php $xml = simplexml_load_file("./onto.owl"); $xml = $xml->children("http://www.w3.org/2002/07/owl#"); var_dump($xml);
結果は、
object(SimpleXMLElement)#2 (1) { ["Class"]=> array(2) { [0]=> object(SimpleXMLElement)#3 (0) { } [1]=> object(SimpleXMLElement)#4 (0) { } } }
つまり、名前空間付きの子要素をとってくる場合、Childrenなどというクソわずらわしいものをつけなければいけません。これはSimpleXMLの仕様です。
で、id:kakku22 さんのやりたかったことをしようとしたら、
<?php $xml = simplexml_load_file("./onto.owl"); $num = 0; foreach ($xml->children("http://www.w3.org/2002/07/owl#") as $owl) { if ($owl->Class instanceof SimpleXMLElement) { $num++; } } echo $num; echo "\n";
とかってやりますかね。
面倒だったのでSubClassは無視しちゃいましたが、まじめにやるなら再帰とか使ってサブツリーを掘っていくのが良いかと。
ところで、もっと簡単にやる方法が・・・XPath を使う
<?php $xml = simplexml_load_file("./onto.owl"); echo count($xml->xpath("//owl:Class")); echo "\n";
これで、
4
が得られます。
なぜかXPathでは名前空間付き要素が取れるんですね!不思議な不思議なPHP!
で、もうちょっとまじめにがんばるなら、ちゃんと名前空間のPrefixを登録してあげます。(こうすれば、定義側で仕様変更があったときにも大丈夫です。ま、実際はほとんど必要ないとは思いますが・・・・)
<?php $xml = simplexml_load_file("./onto.owl"); $xml->registerXPathNamespace("owl", "http://www.w3.org/2002/07/owl#"); echo count($xml->xpath("//owl:Class")); echo "\n";
余談:名前空間付き属性へのアクセス
<?php $xml = simplexml_load_file("./onto.owl"); foreach ($xml->children("http://www.w3.org/2002/07/owl#") as $owl) { if ($owl->Class instanceof SimpleXMLElement) { echo $owl->attributes("http://www.w3.org/1999/02/22-rdf-syntax-ns#")->ID; echo "\n"; } }
追記
今回読み込むオントロジーファイルは結構大きいので,XMLReaderで良かったと思う.
大正解です。そのほうが良いと思いますw デカいファイルを読み込ませるととたんに破綻するのがSimpleXMLのかわいいところw
まぁ、一応、SimpleXMLでも要素は取得できるよ、という参考程度に。