民间,
我正在使用REXML作为示例XML文件:
<Accounts title="This is the test title">
<Account name="frenchcustomer">
<username name = "frencu"/>
<password pw = "hello34"/>
<accountdn dn = "https://frenchcu.com/"/>
<exporttest name="basic">
<exportname name = "basicexport"/>
<exportterm term = "oldschool"/>
</exporttest>
</Account>
<Account name="britishcustomer">
<username name = "britishcu"/>
<password pw = "mellow34"/>
<accountdn dn = "https://britishcu.com/"/>
<exporttest name="existingsearch">
<exportname name = "largexpo"/>
<exportterm term = "greatschool"/>
</exporttest>
</Account>
</Accounts>
我正在阅读这样的XML:
@data = (REXML::Document.new file).root
@dataarr = @@testdata.elements.to_a("//Account")
现在我想获得法国客户的用户名,所以我尝试了这个:
@dataarr[@name=fenchcustomer].elements["username"].attributes["name"]
这失败了,我不想使用数组索引,例如
@dataarr[1].elements["username"].attributes["name"]
会起作用,但我不想那样做,有什么东西我在这里不见了。我想使用数组并使用帐户名称获取法国用户的用户名。
非常感谢。
答案 0 :(得分:3)
我建议您使用XPath
。
对于第一场比赛,您可以使用first
方法,对于数组,只需使用match
。
上面的代码返回帐户“frenchcustomer”的用户名:
REXML::XPath.first(yourREXMLDocument, "//Account[@name='frenchcustomer']/username/@name").value
如果您真的想使用使用@@testdata.elements.to_a("//Account")
创建的数组,可以使用find
方法:
french_cust_elt = the_array.find { |elt| elt.attributes['name'].eql?('frenchcustomer') }
french_username = french_cust_elt.elements["username"].attributes["name"]
答案 1 :(得分:1)
puts @data.elements["//Account[@name='frenchcustomer']"]
.elements["username"]
.attributes["name"]
如果要迭代多个相同的名称:
@data.elements.each("//Account[@name='frenchcustomer']") do |fc|
puts fc.elements["username"].attributes["name"]
end
答案 2 :(得分:0)
我不知道您的@@testdata
是什么,我尝试使用以下测试代码:
require "rexml/document"
@data = (REXML::Document.new DATA).root
@dataarr = @data.elements.to_a("//Account")
# Works
p @dataarr[1].elements["username"].attributes["name"]
#Works not
#~ p @dataarr[@name='fenchcustomer'].elements["username"].attributes["name"]
#@dataarr is an array
@dataarr.each{|acc|
next unless acc.attributes['name'] =='frenchcustomer'
p acc.elements["username"].attributes["name"]
}
#@dataarr is an array
puts "===Array#each"
@dataarr.each{|acc|
next unless acc.attributes['name'] =='frenchcustomer'
p acc.elements["username"].attributes["name"]
}
puts "===XPATH"
@data.elements.to_a("//Account[@name='frenchcustomer']").each{|acc|
p acc.elements["username"].attributes["name"]
}
__END__
<Accounts title="This is the test title">
<Account name="frenchcustomer">
<username name = "frencu"/>
<password pw = "hello34"/>
<accountdn dn = "https://frenchcu.com/"/>
<exporttest name="basic">
<exportname name = "basicexport"/>
<exportterm term = "oldschool"/>
</exporttest>
</Account>
<Account name="britishcustomer">
<username name = "britishcu"/>
<password pw = "mellow34"/>
<accountdn dn = "https://britishcu.com/"/>
<exporttest name="existingsearch">
<exportname name = "largexpo"/>
<exportterm term = "greatschool"/>
</exporttest>
</Account>
</Accounts>
我对rexml不太熟悉,所以我希望有更好的解决方案。但也许有人可以拿我的代码来构建更好的解决方案。