[PHP] simpleXMLでnamespaceにくじけない方法

Pocket
LINEで送る
GREE にシェア
LinkedIn にシェア

以前、officeドキュメントの技術調査しながら、xmllintを学習していたんですが、案件のオーダーが入ったのでしばらく置き去りにしておいた作業をまた再開しました。
 

それはOfficeドキュメントを自由自在にコントロールできるコンバーターツールなんですが、RPAの一貫で独自ツールを作っている人も多いし、それをブログに掲載している人も多いようです。
 

でも肝心のXML操作について書いてくれている人があまりいないのか、ドンピシャな記事に出会えなかったので、備忘録を兼ねて残しておきたいと思います。
 

Officeドキュメント(今回はpptx)のXMLについて

XMLについての扱い方やxmllintマニュアル、PHPのsimpleXMLなどのリファレンスサイトはたくさんあるんですが、どれもnamespaceについての記述が少なく、操作する時に結構苦労してしまいます。
 

ちなみに、pptxのxmlドキュメント(slideデータのみ)は以下のような感じです。
 

 

p,r,aというnamespaceを持っていて、中には属性にまでnamespaceがついているものもあります。
 

 

とりあえず、このxmlに対して、情報検索やデータ取得、DOM追加、削除などを操作できなければ先に進むことができないため、Try&Attachで試しながらコーディングしてみたので、それぞれのやり方を書き残しておきます。

simpleXMLでのnamespace操作法

文字列からxmlデータの読み込み

 

xmlファイルからの読み込み

 

 

プログラムを実行すると、pタグの情報を取得することができますが、ネストになっている内部のnamespace情報はこれだけでは見ることができないので、逐一namespaceアクセスをする必要があります。
 

そして、namespaceは以下のようにするとアクセスができるようになります。
 

$nsは、xmlに定義されているnamespaceを連想配列で取得することが出来ます。
 

またxpathを使う場合は以下のようにピンポイントにアクセスすることもできます。
 

namespace構造の要素の追加

サンプルxmlの任意箇所に要素を追加する場合は以下のようにします。
&nbdsp;

 

xml内部(上の方)にあるこの箇所に<a:hoge cx=”0″ cy=”0″/>という要素を追加してみたいと思います。
 

addChildに$ns[“a”]を付けているところがミソですね。
 

要素の削除

最後に要素の削除ですが、基本形は、要素を抽出して、そのparentNodeからremoveCHildするというJavascriptと同じやり方でいいのですが、foreachなどの内部で行いたいときがありますが、その場合は、削除していくと、順番が変わってkey値がずれていくので、よくトラブルになりがちなので、僕の場合は以下のようにしています。
 

 

無事にデータが削除できていれば完了です。
 

とりあえず、本日はこのへんまで・・・
namespaceは本当にめんどくさいとしか思えない仕様なのですが、セキュリティも含めてこの仕様の利点が何も思い浮かびません。
でも、MS企画に対応するしかないでしょ。
 

また、作業が進んできたら、備忘録を残していきたいと思います。

参考サイト

PHP マニュアル
 

基本的な SimpleXML の使用法
 

SimpleXMLElement クラス
 

PisukeCode – Web開発まとめ
 

PHPプログラミング解説
 

LIG : 一手間必要。PHPでのSimpleXML関数のパース処理
 

Leave a Reply

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です