• ベストアンサー

XML::XPath -- 追加したノードが見付からない

XMLのテンプレートを既存のXMLに追加したのですが、 その後 findnodes() で検索しても合致しません。 XML::XPath::Node::Element->new() を使って作成したものは 合致してくれます。 XML::XPath::XMLParser でパースしたものを追加して findnodes() で合致させるにはどのようにしたらよいのでしょうか。 ------------------------------- use XML::XPath; #### 元のXML my $xmldata = <<EOM; <?xml version="1.0" encoding="UTF-8" ?> <list>   <item>orange</item>   <item>apple</item>   <item>lemon</item> </list> EOM ### 追加するXMLのテンプレート my $xmlappend = <<EOM;   <item>pine</item> EOM ## 追加先ノードを取り出す my $xml = XML::XPath->new( xml=>$xmldata ); my ($list) = $xml->findnodes('/list'); ## 追加用XMLを作成して追加 my $append = XML::XPath::XMLParser->new( xml=>$xmlappend )->parse; $list->appendChild( $append ); ## もういっこ追加。こちらはこの場で作る $newnode = XML::XPath::Node::Element->new('item'); $newtext = XML::XPath::Node::Text->new('banana'); $newnode->appendChild( $newtext ); $list->appendChild( $newnode ); ## 現状確認 → pine は入っていた print $list->toString."\n"; ## item一覧を取得 @nodes = $xml->findnodes('/list/item'); ## 一覧を出力 → 追加した pine が出力されない。 bananaはある。 map{ print $_->toString."\n" } @nodes;

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

XMLParserでパースした追加XMLテンプレートはXMLドキュメントの扱いになるので、 $appendをそっくりそのまま追加すると元のXMLドキュメントに別のXMLドキュメントが要素として追加される・・・ という感じになってしまうのではないでしょうか。 XMLParserでパースしたものから、<item>を改めて抜き出せば大丈夫だと思います。 ---------------------------------------------- ## 追加用XMLを作成して追加 my $append = XML::XPath::XMLParser->new( xml=>$xmlappend )->parse; @items = $append->findnodes('/item'); map{$list->appendChild( $_ );}@items;

dany
質問者

お礼

ありがとうございます。 そうですか、まったく別の扱いになってしまうのですね。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

試してみました。 $nodes = $xml->find('//item'); foreach $node ($nodes->get_nodelist){ print $node->toString.":"; print $node->getParentNode->getTagName."\n"; } の様にしてみると、 <item>pine</item>の親ノードが<list>になっていないことがわかります。

dany
質問者

お礼

ありがとうございます。 どうやら追加したノードは別物として扱われてしまうようですね。 XML::XPath::Node::Element->new で一個ずつ作るサブルーチンを作ることにします。