• ベストアンサー

->の意味

よく->といったものが、 参考スクリプトなどをみていると、 でてくるのですが、いまいちどう 解釈してよいのやらわかりません。 調べてもなかなかみつからず、質問させていただきます。 use XML::XPath; use XML::XPath::XMLParser; my $xpath = XML::XPath->new( filename => shift @ARGV ); my $nodeset = $xpath->find( shift @ARGV ); foreach my $node ( $nodeset->get_nodelist ) { print XML::XPath::XMLParser::as_string( $node ) . "\n"; } XML::XPath->new( filename => shift @ARGV );とか $xpath->find( shift @ARGV );とか $nodeset->get_nodelistは どういった理解をすればよいのでしょうか。 教えていただけますでしょうか。

  • Perl
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

Perl (5以降)には、配列の配列(≒多次元配列)のような 複雑なデータ構造を表現するための「リファレンス」 というものがあります。 -> はそのリファレンスに密接に関係しています。 とりあえずいちばん簡単であろう配列を使って説明しましょう。 @array = (1, 2, 3, 4, 5); で変数arrayは普通の配列ですが、 $array_ref = \(1, 2, 3, 4, 5); #$array_ref = [1, 2, 3, 4, 5]; でも同じ では、変数array_refは配列のリファレンスを保持しています。 アクセスするときは $array[0] というのが普通の配列ですが、 リファレンスの方は $$array_ref[0] のようになります。 リファレンスを辿る(dereference)手間が入るので 記述がちょっと変わります。 で、これは -> 演算子を使って $array_ref->[0] のようにも書けます。 Perl 5ではこのリファレンスを使って オブジェクト指向を実現しています。 質問にある例だと $xpath->find( shift @ARGV ) $xpath はオブジェクトでfindというメソッドを持っていて、それを呼び出しています。 $nodeset->get_nodelist こちらは $nodeset がオブジェクトです。 get_nodelist は名前からするとメソッドでしょうか。 引数がない場合には () は省略することもできます。 後回しにした XML::XPath->new( filename => shift @ARGV ); ですが、 あるオブジェクトを作るとき $o = new クラス名(...); のようにするのですが、これを -> を使って $o = XML::XPath->new(...); と書くことができます。 リファレンスに関する詳しい説明は perlref - Perlのリファレンスとネストしたデータ構造 http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html あたりをどうぞ。

trfnc223
質問者

お礼

ご丁寧にありがとうございました。 省略の記述だったのですね。 リファレンスをもっと勉強するようにします。 ありがとうございました!

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「オブジェクト指向」ってのがキーワードかなぁ. 探せば見付かると思う.

関連するQ&A

  • XML::XPathを使う

    エラーがでて期待する出力が出ず困っています。 ファイル名とXPathのコマンドライン引数をとり、 指定されたパスに一致するノードを出力するものです。 (参考書の写しなので、記述ミスはないと思います。) ■grabber.pl use XML::XPath; use XML::XPath::XMLParser; my $xpath = XML::XPath->new( filename => shift @ARGV ); my $nodeset = $xpath->find( shift @ARGV ); foreach my $node ( nodeset->get_nodelist ) { print XML::XPath::XMLParser::as_string( $node ) . "\n"; } コマンドラインに入力しているものは、 perl grabber.pl data.xml "/inventory/category/item/name" ■data.xml <?xml version="1.0"?> <inventory date="2001"> <category> <item id="2"> <name>aaaa</name> </item> </category> </inventory> です。 perl grabber.pl data.xml "/inventory/category/item/name" としても、下記にエラーが出ます。 Can't locate object method "get_nodelist" via package "nodeset" (perhaps you for got to load "nodeset"?) at grabber.pl line 5. いろいろ試してみたり調べたのですが、 行き詰ってしまいました。 期待する出力は"<name>aaaa</name>"なのですが・・・ どなたかこのエラーの原因がおわかりになるかた いらっしゃいますでしょうか。 環境は以下になります。 ・windowsxp ・activePerl モジュールのインストール済み ・XML-XPath ・XML-Parser 以上です。

    • ベストアンサー
    • Perl
  • PerlによるXMLファイルの解析&出力

    XMLファイルで以下のようなXMLファイルから、 <?xml version="1.0" encoding="Shift_JIS"?> <class3> <Personal> <No>1</No> <Name>相上男</Name> <phone>00-0000</phone> </Personal> <Personal> <No>2</No> <Name>柿句毛子</Name> <phone>11-1111</phone> </Personal> </class3> perlでNameの部分のタグだけ抜き出しXMLファイルに出力するプログラムを組み立てたいです。自分でも以下のようなプログラムを組み立てたのですが、 #!/usr/bin/perl use strict; use Encode; use XML::XPath; use XML::XPath::XMLParser; # 書き込み用にファイルを開く open( OUTPUTFILE, ">Output2.xml" ); # 標準出力に書き出し print &xml_xpath; # ファイルを出力先に設定 select( OUTPUTFILE ); # 出力先を元に戻す select( STDOUT ); # ファイルを閉じる close( OUTPUTFILE ); sub xml_xpath{ my $file = "class3.xml"; my $xp = XML::XPath->new(filename => $file); foreach my $node( $xp->find('/class3/Personal/Name')->get_nodelist){ print Encode::encode("shift_jis", $node )."\n"; } } XML::XPath::Node::Element=REF(0x1036c58c) XML::XPath::Node::Element=REF(0x1036cb8c) と、出てくるだけで動きません。ほとんど初心者なのでまったく見当違いのプログラムを組み立てているかもしれませんが、よろしくおねがいします。

  • XML::XPath でXMLを修正して出力するには?

    XML::XPath を使って以下のようなソースを書きましたが、出力の方法がわかりません。 ++++++++++++++++ use strict; use XML::XPath; my $filename = "test.html"; my $xp = XML::XPath->new(filename=>$filename); my @nodeset = $xp->findnodes("//div[attribute::class='center']//img[attribute::class='right'"); for my $node ( @nodeset ){ print $node->removeAttribute('class'), "\n"; } print $xp; 1; ++++++++++++++++++++++++++++ 最後の print $xp のところで、修正後のXMLを出力したいです。 修正後のXMLをテキストとして出力(変数に入れるでも、標準出力でも)するには、どうすればよいのでしょうか?

    • ベストアンサー
    • Perl
  • XML::XPathでのfor文の記述

    たびたびお世話になります。よろしくお願いいたします。 perlでXML文書をHTMLへ変換しています。 ---------------------------------------- <!-- file.xml --> <root> <jouhou> <mei> <toushu>あ</toushu> <toushu>い</toushu> <toushu>う</toushu> </mei> <mei> <toushu>え</toushu> <toushu>お</toushu> <toushu>か</toushu> </mei> </jouhou> </root> ---------------------------------------- このようなXMLの場合に、XML::XPathで「あ」と「え」などの最初に来る<toushu>取りたいのですが 日によって<mei>の数が異なるため、<mei>の数を取得してその数でforをすることにしました。 が、うまくいきません。 my $xp = new XML::XPath( filename => "./file.xml" ); for(my $j=1;$j<=$xp->findvalue("count(//jouhou/mei/toushu)");$j++){ print $j; #←ここでは1と2が出ます。 print $xpath->find('//jouhou/mei[$j]/toushu')->get_node(1)->string_value; } このままでは全く出なく、["$j"]とすると、出るには出るのですが「あ」が2回出てしまいます。 書き方が違うと思うのですが、()でくくってみても出ません。 ちなみに print $xpath->find('//jouhou/mei[1]/toushu')->get_node($j)->string_value; だと、ちゃんと「あ」と「い」が出ました…。 もし、お分かりになれば教えていただきたいです。 お手数をおかけしますが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • 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;

    • ベストアンサー
    • Perl
  • xmlの値を配列に格納したいんですけどエラーがでてしまう。

    <?xml version="1.0" encoding="UTF-8" ?> <Dataroot> <aaa> <bbb> <ccc>値1</ccc> </bbb> <bbb> <ccc>値2</ccc> </bbb> </aaa> </Dataroot> ---------------------------------------------------------------- のようなXML文書がある時<ccc></ccc>の値を取り出す場合 ---------------------------------------------------------------- Imports System Imports System.IO Imports System.Xml public class Sample public shared sub Main() Dim doc as XmlDocument = new XmlDocument() doc.Load("data.xml") 'XML文書の読み込み Dim root as XmlElement = doc.DocumentElement Dim nodeList as XmlNodeList nodeList = root.SelectNodes("/Dataroot/aaa/bbb")'/cccまでやる方が簡単 Dim node as XmlNode Dim ccclist() As String = Nothing for each node in nodeList ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し next end sub end class としているのですが ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し この行で オブジェクト参照がオブジェクト インスタンスに設定されていません。 とエラーがでて困っています。 これはどのように修正すればよろしいでしょうか? 教えてください。お願いします。

  • スマートフォンで動かない

    http://yoneyone.my-sv.net/XmlSelectBox.htm ページですが以下のjavascriptを修正しスマートフォンで動かす事は可能でしょうか? 解決できない場合、スマートフォンで動かないjavascriptを記述していると思うのですが、 原因ってなんなのでしょうか? 以下がjavascriptです。 function xmlselectbox(id,xml_url,key,func){ var callback_func=func; var outarea=document.querySelector(id); var xml={}; var items=[]; var XHR= new XMLHttpRequest(); while(outarea.hasChildNodes()){ outarea.removeChild(outarea.lastChild); } //XMLのロード(エラー処理省略) XHR.open("GET",xml_url,false); XHR.send(null); if(XHR.status == 200) xml=XHR.responseXML; //if(xml.hasOwnProperty("SelectionLanguage")) //IEは使えない if(typeof xml.hasOwnProperty === "undefined") //とりあえず xml.setProperty("SelectionLanguage","XPath"); //IEにのみ必用 //最初のSELECTBOX生成 items=getitem("/descendant::node()/child::"+key,xml); var first_contener=document.createElement("div"); var first_selectbox=document.createElement("select"); first_selectbox.setAttribute("name",key); first_selectbox.add(new Option(key+"を選択してください","default"),null); for(var i=0;i<items.length;i++){ first_selectbox.add(new Option(items[i].firstChild.nodeValue,items[i].firstChild.nodeValue),null); } //イベント追加 first_selectbox.onchange=select_change(first_selectbox,xml,outarea); first_contener.appendChild(document.createTextNode(key+":")); first_contener.appendChild(first_selectbox); outarea.appendChild(first_contener); first_selectbox.selectedIndex=0; //SELECTBOXをどんどん作成 function select_change(selectbox,xml,outarea){ return function(){ var items=[]; items=getitem("/descendant-or-self::node()/child::" + selectbox.name + "[contains(self::node()/text(),'" + selectbox.value + "')]/child::*",xml); /* *********************************************************************************** normalize-space()は空白をtrimするだけ。 OK items=getitem("/descendant-or-self::node()/child::" + selectbox.name + "[normalize-space(self::node()/text())='" + selectbox.value + "']/child::*",xml); OK items=getitem("//"+selectbox.name+"[normalize-space(./text())='"+selectbox.value+"']/*",xml); ×? items=getitem("/descendant-or-self::" + selectbox.name +"[normalize-space(.)= '" + selectbox.value + "']/*",xml); */ if(items.length>0){ if(selectbox.parentNode.nextSibling){ if(selectbox.parentNode.nextSibling.lastChild.getAttribute("name")==items[0].nodeName) outarea.removeChild(selectbox.parentNode.nextSibling); } var next_contener=document.createElement("div"); var next_selectbox=document.createElement("select"); next_selectbox.setAttribute("name",items[0].nodeName); next_selectbox.add(new Option(items[0].nodeName+"を選択してください","default"),null); for(var i=0;i<items.length;i++){ next_selectbox.add(new Option(items[i].firstChild.nodeValue,items[i].firstChild.nodeValue),null); } //イベント追加 next_selectbox.onchange=select_change(next_selectbox,xml,outarea); next_contener.appendChild(document.createTextNode(items[0].nodeName+":")); next_contener.appendChild(next_selectbox); if(selectbox.parentNode.nextSibling){ outarea.insertBefore(next_contener,selectbox.parentNode.nextSibling); }else{ outarea.appendChild(next_contener); } next_selectbox.selectedIndex=0; }else{ if(typeof callback_func != "undefined") callback_func(selectbox.getAttribute("name"),selectbox.value); } } } //XPATHで検索 function getitem(xpath,xml){ var nodeValues=[]; var NodeList,Nodelength; try{ NodeList = xml.evaluate(xpath,xml,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null); }catch(e){ NodeList = xml.selectNodes(xpath); } Nodelength=NodeList.snapshotLength||NodeList.length; for(var i=0;i<Nodelength;i++){ nodeValues[i]=(typeof(NodeList.snapshotItem)==='undefined')?NodeList.item(i):NodeList.snapshotItem(i); //console.log(nodeValues[i]); } return nodeValues;

  • スクレイピングPHPにおける複数spanについて

    外部のホームページのソースを拾いRSS化するPHPを作成しました。 ***************************************** 外部ホームページ http://hoge.com/index.html ***************************************** <html> <table class="Table100"> <tr> <th class="Name"><h1>えんどう豆</h1></th> <td class="Price">254</td> <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> </tr> </table> </html> ***************************************** スクレイピングPHP http://hagedebu.jp/index.php  ***************************************** <?php class SimpleXMLExtended extends SimpleXMLElement { public function addCData($data) { $dom = dom_import_simplexml($this); $dom->appendChild($dom->ownerDocument->createCDATASection($data)); } } $xml = new SimpleXMLExtended('<rss version="2.0"></rss>'); $channel = $xml->addChild('channel'); $channel->addChild('title', 'TEST RSS'); $dom = new DOMDocument; @$dom->loadHTMLFile('http://hoge.com/index.html'); $xpath = new DOMXPath($dom); foreach ($xpath->query('//*[@class="Table100"]') as $node) { $item = $channel->addChild('item'); $item->addChild('description')->addCData(implode('<br>', [ $xpath->evaluate('string(.//*[@class="Name"]/h1)', $node), $xpath->evaluate('string(.//*[@class="Price"])', $node), $xpath->evaluate('string(.//*[@class="maker"]/span)', $node), ])); } header('Content-Type: application/xml; charset=utf-8'); $xml->asXML('php://output'); ************************************************ 問題点 このPHPでは、 えんどう豆 254 メーカー と表示されてしまいます。 <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> class="makerに複数のspanが入っているため、2つめのspanを認識しません。 当方が表示させたいのは下記のようにspanを両方とも表示させたいです。 またはひとつしか表示させることができない場合は、「メーカー」ではなく「遠藤農園」を優先表示させたいです。 このように表示させるためにはどうすればよいでしょうか? 希望表示 えんどう豆 254 メーカー 遠藤農園 または えんどう豆 254 遠藤農園 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • JavaによるXMLの読み込みについて

    現在、JavaでXMLを読みたく色々なサイト様を参考にさせて頂き プログラムを作成しております。 その結果、下記のようなプログラムで要素名を取得することは出来たのですが、 「属性名」と「属性の値」を読み込み表示することが中々上手くいきません。 どこに何を追加したらよいでしょうか。宜しければ教えて下さい。 -- sample.java -- sample.xml -------------------------------------- import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class sample { public static void main(String[] argv) { sample a = new sample(); a.runner(); } final static String file = "sample.xml"; public void runner() { DocumentBuilderFactory factory; DocumentBuilder builder; Node root; try { factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); factory.setValidating(true); root = builder.parse(file); showNodes(root, " "); } catch (ParserConfigurationException e0) { System.out.println(e0.getMessage()); } catch (SAXException e1){ System.out.println(e1.getMessage()); } catch (IOException e2) { System.out.println(e2.getMessage()); } } public void showNodes(Node node, String space) { NodeList nodes = node.getChildNodes(); for (int i=0; i<nodes.getLength(); i++) { Node node2 = nodes.item(i); if(!node2.getNodeName().equals("#text")){ System.out.println(space + "<" + node2.getNodeName() + ">"); showNodes(node2, space + " "); } } } }

    • ベストアンサー
    • Java
  • XMLデータの中の改行コードについて

    Windows2K VC++6.0 msxml3.dll 環境でXMLデータ処理をしています。 XMLデータ <aa> <Data>内容</Data> </aa> pXMLDom->getElementsByTagName(L"Data", &NodeList); pIDOMNodeList->get_item(0, &Node); Node->get_text(&bstrText); XMLDOMを用いて<Data>内容</Data>のデータを取ると『内容』が取れますが、内容の中で【改行コード(CRLF(10進数13,10))】が『LF(10)』になってしまいますが、 どうしてでしょうか。

専門家に質問してみよう