プロが教えるわが家の防犯対策術!

Rubyにおける、XPathの関数「text()="x"」への変数の使用方法

お世話になります。

RubyにてXPathの関数「text()="x"」"x"の部分に変数を使用したいと思い、コードを作成しています。
text() 関数のところで困っています。

例えば
<?xml version="1.0" encoding="UTF-16"?>
<NameRoot>
<Text>
<Name>あああああ</Name>
<No>001</No>
</Text>
<Text>
<Name>いいいいい</Name>
<No>002</No>
</Text>
<Text>
<Name>ううううう</Name>
<No>003</No>
</Text>
</NameRoot>

の内容のファイルを読み込み、その中から該当するNoに相当するNameを取得しようと
しています。
で、書いたのが下記のような内容なのですが、gettestクラスのgetNameメソッドにて
コメントアウトしてある行であれば、決め打ちでNo="001"の物を取ってこれるのですが、
ここに引数として渡されたローカル変数の、idを使用しようとするとnode変数にNilClass
が返ってきて取得できません。
文字列リテラルを色々調べてみたのですが、どうも上手く行かず困っています。
他愛も無い質問かもしれませんが、大変困っています。
どなたか知恵をお貸しくださいますようお願い致します。

class gettest
def getName(id)
#↓これがきちんと動きません
node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="#{id}")]')

#↓こちらは当然ながら動きます
# node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="001"]')

path = (node.xpath + "/../Name")
@name = @masterdata.elements[path].text()
end
end

class main
def edit
@mastername = ""
@mastername = @master.getName("001")
print @mastername
end
end

A 回答 (2件)

#{式} の展開は、" " の中だけです。

' ' の中では効きません。

node = REXML::XPath.first(@masterdata, "//NameRoot/Text/No[text()='#{id}')]")
    • good
    • 0
この回答へのお礼

初歩的なミスですね・・・
お時間取らせてしまってすいませんでした。
大変助かりました、ありがとうございました!

お礼日時:2010/03/09 18:48

未検証


#Ruby碌にやってないから知らんけど、XMLファイルというかリソースというかそういうもの読み込む部分無くて大丈夫なのかなあ?

node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="001"
)
]
'
)

閉じ丸括弧一つ多くね?

メモ
============================
RubyやってないのでここからC#の話が中心ー。
id = '" or "" = "'
とか…
node = REXML::XPath.first(@masterdata, '//NameRoot/Text/No[text()="" or "" = ""]')

安全にやりたい。外側でチェックしているならまだいいけど。
あと、今回見たいな文法ミスのケースで例外吐いてくれない。
#ま、ひょっとしたら今回みたいなSyntax Errorとノードが実際に見つからなかった時の戻り値って違うのかもしれない。
その場合は以下は不要

こうやってノードを作って足し、検索すればいいんじゃないかなー
.NET Frameworkのリファレンスには名前空間接頭辞以外の文法エラーについて書いてないけどどーなんだろう。

using System;



namespace Q5736805

{

class MainClass

{

public static void Main (string[] args)

{

}



public static System.Xml.XmlNode findNode(string x){

System.Xml.XmlDocument doc = new System.Xml.XmlDocument();

System.Xml.XmlDocument doc2 = new System.Xml.XmlDocument();

/* 間違って上書きしないようにしている。メモリの無駄な気もするが。*/

doc.Load("C:\\aaa.xml");



doc2 = doc.CloneNode(true);



System.Xml.XmlElement text = doc2.CreateElement("Text","");

System.Xml.XmlElement no = doc2.CreateElment("No");

no.InnerText = "XXX";

text.AppendChild(no);

doc2.DocumentElement.AppendChild(text);

System.Xml.XmlNode ret = doc2.SelectSingleNode("//NameRoot/Text/No[text()=../No[last()]/text()]");

if (ret == null){

throw new Exception();

}



return (ret != text) ? ret : null ;

}

}

}

nullだったら文法間違いだから例外を吐くことにして、そうでなければ戻り値を返す、と。できるんじゃないかな。
    • good
    • 0
この回答へのお礼

ありがとうございました。
閉じ括弧は実際のプログラムからサンプルとして抜き出す際にやってしまいました。
申し訳ありませんでした。
参考になりました!

お礼日時:2010/03/09 18:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!