REXML 在 ruby​​ 中解析 XML

发布于 2025-01-05 08:08:50 字数 1459 浏览 0 评论 0原文

各位,

我正在使用 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")

现在我想获取 frenchcustomer 的用户名,所以我尝试了这个:

@dataarr[@name=fenchcustomer].elements["username"].attributes["name"]

这失败了,我不想使用数组索引,因为示例

@dataarr[1].elements["username"].attributes["name"]

可以工作,但我不想这样做,我这里缺少什么吗?我想使用该数组并使用帐户名称获取法国用户的用户名。

多谢。

Folks,

I am using REXML for a sample XML file:

<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>

I am reading the XML like this:

@data = (REXML::Document.new file).root
@dataarr = @@testdata.elements.to_a("//Account")

Now I want to get the username of the frenchcustomer, so I tried this:

@dataarr[@name=fenchcustomer].elements["username"].attributes["name"]

this fails, I do not want to use the array index, for example

@dataarr[1].elements["username"].attributes["name"]

will work, but I don't want to do that, is there something that i m missing here. I want to use the array and get the username of the french user using the Account name.

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔戏命师 2025-01-12 08:08:50

我建议您使用XPath

对于第一次匹配,可以使用first方法,对于数组,只需使用match

上面的代码返回帐户“frenchcustomer”的用户名:

REXML::XPath.first(yourREXMLDocument, "//Account[@name='frenchcustomer']/username/@name").value

如果您确实想使用使用 @@testdata.elements.to_a("//Account") 创建的数组,您可以使用 查找方法:

french_cust_elt = the_array.find { |elt| elt.attributes['name'].eql?('frenchcustomer') }
french_username = french_cust_elt.elements["username"].attributes["name"]

I recommend you to use XPath.

For the first match, you can use first method, for an array, just use match.

The code above returns the username for the Account "frenchcustomer" :

REXML::XPath.first(yourREXMLDocument, "//Account[@name='frenchcustomer']/username/@name").value

If you really want to use the array created with @@testdata.elements.to_a("//Account"), you could use find method :

french_cust_elt = the_array.find { |elt| elt.attributes['name'].eql?('frenchcustomer') }
french_username = french_cust_elt.elements["username"].attributes["name"]
风追烟花雨 2025-01-12 08:08:50
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
puts @data.elements["//Account[@name='frenchcustomer']"]
      .elements["username"]
      .attributes["name"]

If you want to iterate over multiple identical names:

@data.elements.each("//Account[@name='frenchcustomer']") do |fc|
  puts fc.elements["username"].attributes["name"]
end
单身狗的梦 2025-01-12 08:08:50

我不知道你的@@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不太熟悉,所以我希望有更好的解决方案。但也许有人可以利用我的代码来构建更好的解决方案。

I don't know what your @@testdata are, I tried with the following testcode:

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>

I'm not very familiar with rexml, so I expect there is a better solution. But perhaps aomebody can take my code to build a better solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文