SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

PHPでDOMを操作する

PHP 5のDOMエクステンションで、DOMツリーをゼロから作成

ノードを複製する

 ノードの複製とは、同じ型の新しいノードを作成し、(必要なら)現在のノードと同じコンテンツに設定することを意味します。ノードを複製するにはcloneNodeメソッドを使います。

cloneNodeメソッド
DOMNode DOMNode::cloneNode([ bool $deep])

 現在のノードの複製を作成します。引数$deepは、現在のノードの子もコピーするかどうかを指定するものです。デフォルト値はFALSE(コピーしない)です。例えば、次のコードは要素<author>を複製し、元の要素<author>の子として付加します。図4に結果を示します。

//Set the reference node
$author = $root->getElementsByTagName('author')->item(0);
//Call the cloningNode function 
cloningNode($author); 
//This function clone the $currentNode
function cloningNode($currentNode)
   {
      
   $clonenode = $currentNode -> cloneNode(true);
      $newnode = $currentNode->appendChild($clonenode);   
   }
図4 ノードの複製: 子ノード<author>を複製して元のノード<author>に付加した結果。ノードのテキスト値を取得すると子ノードのテキスト値も取得されるので、元のノードのテキスト値は二重になる
図4 ノードの複製: 子ノード<author>を複製して元のノード<author>に付加した結果。ノードのテキスト値を取得すると子ノードのテキスト値も取得されるので、元のノードのテキスト値は二重になる

子ノードを削除する

 ノードをDOMツリーから削除するにはremoveChildメソッドを使います。

removeChildメソッド
DOMNode DOMNode::removeChild(DOMNode $oldnode)

 この関数は子ノードを削除します。引数$oldnodeは削除する子ノードです。例えば、次のコードは子ノード<bibliography>をBooks.xml文書から削除します。結果(図5)を見ると、bibliographyノードがなくなっていることが分かります。

//Get a reference to the bibliography node
$bibliography = $root->getElementsByTagName(
   'bibliography')->item(0);
//Call the removingChild function 
removingChild($bibliography);
//This function remove the $currentNode node
function removingChild($currentNode)
{
   $oldbibliography = $root->removeChild($currentNode);   
}   
図5 ノードの削除: 最後の子ノード(先ほどappendChildメソッドで挿入した<bibliography>)を削除してからノードの名前と値をリストすると、ノードが本当に削除されたことが分かる
図5 ノードの削除: 最後の子ノード(先ほどappendChildメソッドで挿入した<bibliography>)を削除してからノードの名前と値をリストすると、ノードが本当に削除されたことが分かる

ノードを置換する

 既存のノードを新しいノードに置き換えるには、replaceChildメソッドを使います。

replaceChildメソッド
DOMNode DOMNode::replaceChild(DOMNode $newnode, DOMNode $oldnode)

 この関数は新しいノードがまだ別の親の子でなければ、$oldnodeを新しい子ノード$newnodeに置き換えます。

 例えば、子ノードISBNを新しい子ノードcodeに置き換えるには次のようにします。

//Get the ISBN node
$element = $dom->getElementsByTagName('ISBN')->item(0); 
//Create the new <code> element 
$code = $dom->createElement('code', '909090');
//Call the replacingNode function 
replacingNode($code,$element);
//This function replaces $currentNode with $node 
function replacingNode($currentNode, $node)
{
   $node->parentNode->replaceChild($currentNode, $node);   
}   

 結果(図6)を見ると、ノードが置き換えられていることが分かります。

図6 ノードの置換: 文書のこの部分でノード<ISBN>が新しいノード<code>に置き換えられている
図6 ノードの置換: 文書のこの部分でノード<ISBN>が新しいノード<code>に置き換えられている

ノードをインポートする

 現在のツリーに別のツリーからノードをコピーするにはimportNodeメソッドを使います。

importNodeメソッド
DOMNode DOMDocument::importNode(DOMNode $importedNode [,bool $deep])

 この関数は新しいノードがまだ別の親の子でなければ、$oldnodeを新しい子ノード$newnodeに置き換えます。このメソッドはノードを別のXML文書からインポートし、現在の文書のDOMツリーに挿入します。引数$importedNodeはインポートするノードです。インポートされるノードは元のノードの''コピー''なので、インポートによって外部のツリーが変更されることはありません。引数$deepはインポートするノードをディープコピーするかどうかを指示するものです。TRUEのときは、ノードの部分ツリー全体がインポートされ、FALSEのときは、直接のノードだけがインポートされます。

 例として、ノード<continue>をBook_continue.xmlファイルからBook.xmlにインポートすることを考えます。Book_continue.xml文書の内容は次のとおりです。

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!--chapter V-->
<continue>
  <chapter_V>
   <title>XPath</title>
   <content>XPath is language for...</content>
  </chapter_V>
  
  <![CDATA[
     This chaper is a bonus to...
     ]]>
  
  <printing cap_I="click_here_for_chapter_I" 
    cap_II="click_here_for_chapter_II"   
    cap_III="click_here_for_chapter_III"
    cap_IV="click_here_for_chapter_IV" 
    cap_V="click_here_for_chapter_V" />
  
</continue>

 ノード<continue>をインポートするコードは次のようになります。

<?php
$olddoc = new DOMDocument;
$olddoc->load("Book_continue.xml");
// The node we want to import to a new document
$node = $olddoc->getElementsByTagName("continue")->item(0);
$newdoc = new DOMDocument;
$newdoc->formatOutput = true;
$newdoc->load("Book.xml");
// Import the node, and all its children, to the document
$node = $newdoc->importNode($node, true);
// And then append it to the root node
$newdoc->documentElement->appendChild($node);
echo "\nThe 'new document' after copying the nodes into it:\n";
$root = $newdoc->firstChild;
function getNodesInfo($node)
{
   if ($node->hasChildNodes())
   {
      $subNodes = $node->childNodes;
      foreach ($subNodes as $subNode)
      {
         if (($subNode->nodeType != 3) || 
            (($subNode->nodeType ==3) &&
            (strlen(trim($subNode->wholeText))>=1)))   
         {
         echo "Node name: ".$subNode->nodeName."\n";
         echo "Node value: ".$subNode->nodeValue."\n";
      }
      getNodesInfo($subNode);         
      }
   }      
}
getNodesInfo($root);   
?>

 図7に結果を示します。

図7 ノードのインポート: <continue>ノードをBook_continue.xmlからインポートしてBook.xmlツリーの最後に挿入すると、Book.xmlはこのようになる
図7 ノードのインポート: <continue>ノードをBook_continue.xmlからインポートしてBook.xmlツリーの最後に挿入すると、Book.xmlはこのようになる

次のページ
ノードの等値性をチェックする

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Octavia Andreea Anghel(Octavia Andreea Anghel)

経験豊富なPHP開発者。現在は、国内外のソフトウェア開発コンテストに参加するプログラミングチームの主任トレーナーを務める。国レベルの教育プロジェクト開発のコンサルティングも担当している。共著書に『XML technologies?XML in Java』があり、XML部分の執筆を担当。PHPやXML...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4278 2009/08/27 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー