<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SimpleXML &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/simplexml/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Tue, 14 Dec 2010 02:00:43 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>PHPでXMLの名前空間つきタグを読み込む色々</title>
		<link>https://blog.mach3.jp/2010/12/14/various-xml-on-php.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Tue, 14 Dec 2010 02:00:43 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Namespace]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[SimpleXML]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=1239</guid>

					<description><![CDATA[PHPのSimpleXMLでRSSを読み込もうと思ったら、名前空間つきのタグが読み込めなかったので、色々な方法を試してみた備忘録。 実験の対象として、はてなブックマークのホットエントリのRSSを使ってみます。 Simpl [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>PHPのSimpleXMLでRSSを読み込もうと思ったら、名前空間つきのタグが読み込めなかったので、色々な方法を試してみた備忘録。</p>



<figure class="wp-block-image"><img decoding="async" src="http://lh4.ggpht.com/_JJkNs5Ixl70/TQYhLrkHwpI/AAAAAAAABHE/fvW42rTywRo/201012132235.png" alt="PHPでXMLの名前空間つきタグを読み込む色々"/></figure>



<p></p>



<span id="more-1239"></span>



<p>実験の対象として、はてなブックマークのホットエントリのRSSを使ってみます。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$url = <span class="hljs-string">"http://b.hatena.ne.jp/hotentry.rss"</span>;
$str = file_get_contents( $url );
</code></span></pre>


<h2 class="wp-block-heading">SimpleXMLを使う方法</h2>



<p>普通にSimpleXMLで読み込むと、<dc:date>や<hatena:bookmarkcount>など、<em>名前空間</em>プレフィックスつきのタグを読み込むことが出来ません。</hatena:bookmarkcount></dc:date></p>


<pre class="wp-block-code"><span><code class="hljs language-php">$simplexml = simplexml_load_string( $str );
var_dump( $simplexml );
</code></span></pre>


<figure class="wp-block-image"><img decoding="async" src="http://lh3.ggpht.com/_JJkNs5Ixl70/TQYh-Hhc3gI/AAAAAAAABHI/4b57ADi-xzg/201012132234.png" alt="消えてしまう名前空間プレフィックスつきタグ"/></figure>



<p></p>



<p>SimpleXMLで名前空間つきタグを扱うには、childrenメソッドを使います。例えば、<em><hatena:bookmarkcount></hatena:bookmarkcount></em>の値を取得する場合、 次のように掘っていく必要があります。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$simplexml-&gt;item&#91;$i]-&gt;children(<span class="hljs-string">"hatena"</span>, <span class="hljs-keyword">true</span>)-&gt;bookmarkcount;
</code></span></pre>


<p>ループでitem要素全てまとめて処理してみます。 それぞれのitem要素にhatena-&gt;bookmarkcountが追加されます。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$simplexml = simplexml_load_string( $str );
$i = count( $simplexml-&gt;item );
<span class="hljs-keyword">while</span>( $i-- ){
    $simplexml-&gt;item&#91;$i]-&gt;hatena-&gt;bookmarkcount = $simplexml-&gt;item&#91;$i]-&gt;children(<span class="hljs-string">"hatena"</span>, <span class="hljs-keyword">true</span>)-&gt;bookmarkcount;
}
var_dump( $simplexml );
</code></span></pre>


<h2 class="wp-block-heading">DOMDocumentクラスを使う</h2>



<p>DOM文書を読み込むためのDOMDocumentクラスを使ってみます。 JavaScriptでも使うような、<em>getElementsByTagName</em>なんていうお馴染みのメソッドを使って文書構造を掘っていきます。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$dom = DOMDocument::loadXML( $str );
<span class="hljs-keyword">foreach</span>( $dom-&gt;getElementsByTagName(<span class="hljs-string">"item"</span>) <span class="hljs-keyword">as</span> $item ){
    <span class="hljs-keyword">foreach</span>( $item-&gt;childeNodes <span class="hljs-keyword">as</span> $node ){
        <span class="hljs-keyword">if</span>( $node-&gt;nodeType === <span class="hljs-number">1</span> ){
            <span class="hljs-keyword">echo</span> <span class="hljs-string">"{$node-&gt;nodeName} : {$node-&gt;nodeValue}"</span>;
        }
    }
}
</code></span></pre>


<p><strong>nodeType</strong>には、ノードの種類が整数で渡されています。上で言う「1」はエレメントノードですね。 勿論、プレフィックスつきのタグも問題なく読み込めます。</p>



<p>cf) <a href="http://www.php.net/manual/ja/dom.constants.php">PHP: 定義済み定数 &#8211; Manual</a></p>



<p>出力時に楽なように、エントリーをまとめて一つの配列に突っ込んでみます。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$dom = DOMDocument::loadXML( $str );
$entries = <span class="hljs-keyword">array</span>();
<span class="hljs-keyword">foreach</span>( $dom-&gt;getElementsByTagName( <span class="hljs-string">"item"</span> ) <span class="hljs-keyword">as</span> $item ){
    $entry = <span class="hljs-keyword">array</span>();
    <span class="hljs-keyword">foreach</span>( $item-&gt;childNodes <span class="hljs-keyword">as</span> $node ){
        <span class="hljs-keyword">if</span>( $node-&gt;nodeType !== <span class="hljs-number">1</span> ) <span class="hljs-keyword">continue</span>;
        <span class="hljs-keyword">if</span>( $item-&gt;getElementsByTagName( $node-&gt;nodeName )-&gt;length &gt; <span class="hljs-number">1</span> ){
            <span class="hljs-keyword">if</span>( !<span class="hljs-keyword">isset</span>( $entry&#91; $node-&gt;nodeName ] ) ){
                $entry&#91; $node-&gt;nodeName ] = <span class="hljs-keyword">array</span>();
            }
            array_push( $entry&#91; $node-&gt;nodeName ], $node-&gt;nodeValue );
        } <span class="hljs-keyword">else</span> {
            $entry&#91; $node-&gt;nodeName ] = $node-&gt;nodeValue;
        }
    }
    array_push( $entries, $entry );
}
var_dump( $entries );
</code></span></pre>


<p>複数あるタグは配列で対応。書いてみたものの…DOMDocumentのまま使った方が使いやすい気もしたり。<br />
むしろこういう使い方するならSimpleXML使った方がよいですね。</p>



<h2 class="wp-block-heading">XMLReaderクラスを使う</h2>



<p>SimpleXMLやDOMDocumentが、XMLの情報をドッカンと丸ごとメモリに置いておくのに大して、<br />
XMLReaderはfopenのようにポインタの位置だけを保持しておく為、メモリに優しく高速。らしい。<br />
ですが、ポインタの位置だけだと正直使い辛いのも事実。</p>


<pre class="wp-block-code"><span><code class="hljs language-php">$xml = XMLReader::load( $url, <span class="hljs-keyword">null</span>, LIBXML_NOBLANKS );
<span class="hljs-keyword">while</span>( $xml-&gt;read() ){
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"{$xml-&gt;nodeType} : {$xml-&gt;name} = {$xml-&gt;value} @ {$xml-&gt;depth} &lt;br /&gt;"</span>;
}
</code></span></pre>


<p>$xml-&gt;read()でノードを一つずつ読み進んでいく感じ。<br />
多階層なXMLを読んでいくのは骨が折れそう。<br />
これは重た～いXMLを読まなきゃいけない時用の代物ですね。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p>名前に違わず相当楽ですね、SimpleXML。<br />
名前空間つきのタグも処理したい場合等は、DOMDocumentの方がシンプルに処理出来そう。<br />
XMLReaderはパフォーマンスを意識したい場合に。</p>



<p>上手に使い分けたいですね！</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<dl>
<dt>2010/12/18</dt>
<dd>マニュアルのリンクを修正</dd>
</dl>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
