hiroshimo
あなたも質問に答えられます!
ウォッチリストに追加
- 状態:終了
- 回答数:3 / 45件
- 回答ポイント:80ポイント
- 登録:2008-02-12 19:51:46
- 終了:2008-02-13 17:45:37
- カテゴリー:
ウェブ制作
フローを示すだけではアレなんで...
$str = <<< EOL
<?xml version="1.0" encoding="UTF-8"?>
<docs xmlns:ns="http://hoge/fuga/">
<document>
<note ns:data="foo">abcde</note>
</document>
<document>
<note ns:data="hoo">edcba</note>
</document>
<document>
<note data="poo">123</note>
</document>
<document>
<note ns:data="boo">abcde</note>
</document>
</docs>
EOL;
$prefix = ''; $ns = '';
// 接頭辞や名前空間が既知なら上で定義すれば下3行は不要
if (preg_match('/xmlns:([-\w.]+)="(.+?)"/', $str, $tmp)){
$prefix = $tmp[1]; $ns = $tmp[2];
}
preg_match_all('/\s'.$prefix.':([-\w.]+)="(.*?)"/', $str, $tmp);
var_dump($tmp[2]);
// simplexml での処理が必要ならこの先も
//$xml = simplexml_load_string($str);
//$xml->registerXPathNamespace('namespace', $ns);
//$res = $xml->xpath('//note[@namespace:data="foo"]');
//var_dump($res);
// 次の行が得られる
// array(1) { [0]=> object(SimpleXMLElement)#2 (1) { [0]=> string(5) "abcde" } }
array(3) { [0]=> string(3) "foo" [1]=> string(3) "hoo" [2]=> string(3) "boo" }
回答ありがとうございます。非常にためになりました。少し質問のしかたがまずかったように思うので再度提示させていただきたいと思います。
<document>
<note data="foo">A</note>
<note data="bar">B</note>
</document>
うえのようなXMLがあったとして、AとかBを取り出そうとしたらこうですよね?
foreach ($xml as $document) {
echo $document->note, '
';
}
fooとかbarを取り出そうとしたら、こうですよね。
foreach ($xml as $document) {
echo $document->note[data], '
';
}
これをしたいのですが、dataにns:という接頭辞が付いているとうまくいきません。
foreach ($xml as $document) {
echo $document->note[ns:data], '
';
}
というようなことを解決したいのですが・・・。どうしたらいいのでしょう?
$sample = array(); $data = @simplexml_load_file(XMLのURL); $sample[] = $data->document->note;
こうゆう事でしょうか。
documentが複数ある場合は
$sample = array();
$data = @simplexml_load_file(XMLのURL);
foreach($data->document as $value){
$sample[] = $value->note;
}
という感じですかね。
名前空間が指定されている属性値を指定して取出したいという事でしょうか?
$str = <<< EOL
<?xml version="1.0" encoding="UTF-8"?>
<docs xmlns:ns="http://hoge/fuga/">
<document>
<note ns:data="foo">abcde</note>
</document>
<document>
<note ns:data="foo">edcba</note>
</document>
<document>
<note data="foo">123</note>
</document>
<document>
<note ns:data="boo">abcde</note>
</document>
</docs>
EOL;
$xml = simplexml_load_string($str);
$xml->registerXPathNamespace('namespace', 'http://hoge/fuga/');
var_dump($xml->xpath('//note[@namespace:]'));print "<br>\n";
$res = $xml->xpath('//note[@namespace:data="foo"]');
var_dump($res);
結果は、
array(2) {
[0]=>
object(SimpleXMLElement)#2 (1) {
[0]=>
string(5) "abcde"
}
[1]=>
object(SimpleXMLElement)#3 (1) {
[0]=>
string(5) "edcba"
}
}
そうじゃなくて、どんな属性が使われているかなら、
一旦 file_get_contents などで読み込み、
名前空間の接頭辞(xmlns をキーにして探す)を preg_match() 等で見つけて、
その接頭辞のついている属性を preg_match_all で探して配列に入れる
という手順が考えられます。
http://jp.php.net/manual/ja/function.simplexml-element-registerX...
おとなり質問
この質問・回答へのコメント
====
回答数制限&コメントが付けられない なのでこちらか失礼します。
$str = <<< EOL
<?xml version="1.0" encoding="UTF-8"?>
<docs xmlns:ns="http://hoge/fuga/">
<document>
<note ns:data="foo">abcde</note>
</document>
<document>
<note ns:data="hoo">edcba</note>
</document>
<document>
<note data="poo">123</note>
</document>
<document>
<note ns:data="boo">ghijk</note>
</document>
</docs>
EOL;
$prefix = 'ns';
$xml = simplexml_load_string($str);
foreach ($xml as $x){
print 'attribute = '.$x->note->attributes($prefix, 1)."\n";
print 'children = '.$x->children()."\n";
print "\n";
}
こんな感じで、ご希望のものに近付いたのではないかと思うのですが、いかがでしょうか?
simplexml を熟知している訳ではないので、マニュアルを読み返してみて見つけました。
これを知っていれば、回答として示したものは、もっとスッキリしたものだったのに...
僕自身も大変勉強になりました。
====
tezcelloさん、ありがとうございました!
attributes属性にprefixを指定できるとは知りませんでした。すっきり解決しました。
ただ、間借りしているサーバーだと SimpleXMLElement::attributes() expects at most 1 parameter, 2 given というエラーが出るんですよね。調べたらphpが5.0.4でした。5.2.5 だと問題なかったんですが。
今回は大変勉強になりました。ありがとうございました。
5.1.x -> 5.2.x の際に、is_prefix が追加になったという記事が見つかりました。
という事は、接頭辞ではなく名前空間を指示すればよいのでは?
$x->note->attributes('http://hoge/fuga/', 1)
って感じで。
26ポイント

