PHPを使用してXMLデータを処理する場合、 SimplexML_Load_Stringは、XML文字列をオブジェクト構造に変換して簡単にアクセスして操作するための非常に便利な機能です。ただし、多くの開発者は、XMLを名前空間で扱う際に一般的な問題に遭遇します。Simplexml_load_Stringは、名前空間の要素を正しく認識またはアクセスしていないようです。
この記事では、この問題の原因を詳細に調査し、1つの記事でそれらを理解し解決するのに役立つ明確なソリューションを提供します。
まず、名前空間を含むXML文字列である例を見てみましょう。
<span><span><span class="hljs-meta"><?xml version=<span class="hljs-string">"1.0"</span></span></span><span>?>
</span><span><span class="hljs-tag"><<span class="hljs-name">root</span></span></span><span> </span><span><span class="hljs-attr">xmlns:h</span></span><span>=</span><span><span class="hljs-string">"http://www.w3.org/TR/html4/"</span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:table</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:tr</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:td</span></span></span><span>>Apples</span><span><span class="hljs-tag"></<span class="hljs-name">h:td</span></span></span><span>>
</span><span><span class="hljs-tag"><<span class="hljs-name">h:td</span></span></span><span>>Bananas</span><span><span class="hljs-tag"></<span class="hljs-name">h:td</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">h:tr</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">h:table</span></span></span><span>>
</span><span><span class="hljs-tag"></<span class="hljs-name">root</span></span></span><span>>
</span></span>
次のコードを使用して解析しようとする場合:
<span><span><span class="hljs-variable">$xmlString</span></span><span> = <span class="hljs-string"><<<XML
<?xml version="1.0"?>
<root xmlns:h="http://www.w3.org/TR/html4/">
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
</root>
XML</span>;
</span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-title function_ invoke__">simplexml_load_string</span></span><span>(</span><span><span class="hljs-variable">$xmlString</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">print_r</span></span><span>(</span><span><span class="hljs-variable">$xml</span></span><span>->table);
</span></span>
$ xml->テーブルが結果を返さないことがわかります。これは、 Simplexml_load_stringがプレフィックス型の名前空間タグ( H:テーブルなど)を処理しないためです。
XMLでは、名前空間が要素名の競合を回避するために使用されます。たとえば、HのH :テーブルは、実際にはXMLNSを指す参照プレフィックスです。H= "http://www.w3.org/tr/html4/" 。これにより、XMLはより拡張可能で整理されますが、追加の解析の難しさももたらします。
SimplexMLelementクラスが提供するChildren()およびgetNamesSpaces()メソッドを使用して、名前空間の要素にアクセスできます。
<span><span><span class="hljs-variable">$namespaces</span></span><span> = </span><span><span class="hljs-variable">$xml</span></span><span>-></span><span><span class="hljs-title function_ invoke__">getNamespaces</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-comment">// 出力結果:['h' => 'http://www.w3.org/TR/html4/']</span></span><span>
</span></span>
<span><span><span class="hljs-variable">$h</span></span><span> = </span><span><span class="hljs-variable">$xml</span></span><span>-></span><span><span class="hljs-title function_ invoke__">children</span></span><span>(</span><span><span class="hljs-variable">$namespaces</span></span><span>[</span><span><span class="hljs-string">'h'</span></span><span>]);
</span><span><span class="hljs-variable">$tr</span></span><span> = </span><span><span class="hljs-variable">$h</span></span><span>->table->tr;
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$tr</span></span><span>->td </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$td</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$td</span></span><span> . PHP_EOL;
}
</span></span>
出力結果:
<span><span><span class="hljs-attribute">Apples</span></span><span>
Bananas
</span></span>
XPath Queryメソッドを使用してデータを取得する場合は、 RegisterXPathNamesPaceメソッドを介して名前空間を登録できます。
<span><span><span class="hljs-variable">$xml</span></span><span> = </span><span><span class="hljs-title function_ invoke__">simplexml_load_string</span></span><span>(</span><span><span class="hljs-variable">$xmlString</span></span><span>);
</span><span><span class="hljs-variable">$xml</span></span><span>-></span><span><span class="hljs-title function_ invoke__">registerXPathNamespace</span></span><span>(</span><span><span class="hljs-string">'h'</span></span><span>, </span><span><span class="hljs-string">'http://www.w3.org/TR/html4/'</span></span><span>);
</span><span><span class="hljs-variable">$tds</span></span><span> = </span><span><span class="hljs-variable">$xml</span></span><span>-></span><span><span class="hljs-title function_ invoke__">xpath</span></span><span>(</span><span><span class="hljs-string">'//h:td'</span></span><span>);
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$tds</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$td</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$td</span></span><span> . PHP_EOL;
}
</span></span>
このアプローチは、意味的に明確であるだけでなく、複雑なXML構造を扱う際の柔軟性もあります。
simplexml_load_stringを使用して名前空間でXMLを解析する場合、子要素にアクセスできないことがわかった場合、XMLが間違っていると疑わないでください。子供() 、 getNamesSpaces() 、およびRegisterXPathNamesPace()メソッドを理解して使用すると、名前空間によって引き起こされるトラブルを簡単にクラックできます。
名前空間の処理は少し面倒ですが、一度マスターされると、さまざまな標準化されたXMLデータソースにシームレスに接続し、PHPアプリケーションの統合機能を強化できます。この記事があなたがこの問題を徹底的に理解するのに役立つことを願っています!