0

我正在使用 Ruby、Norkigiri 和 Nori。我想对我应该如何解析这个 XML 文件有一些想法。

在此模式中,一个实体可以包含多个联系人。

我需要返回以下内容的哈希:

  • :ID
  • :名
  • :姓
  • :preferred_email
  • :经理

我考虑过使用 xpath 来尝试返回首选的电子邮件联系人。

entities = doc.xpath("/entity_list/entity").each do |entity|
   puts entity.xpath("contact_list/contact[contains(type,'Email') and contains(preferred, '1')]")
end



  <entity>
    <id>21925</id>
    <last_name>Smith</last_name>
    <first_name>John</first_name>
    <preferred_name>Johnny</preferred_name>
    <manager>Timmy</manager>
    <dob>1970-01-01</dob>
    <type>individual</type>
    <contact_list>
      <contact>
        <type>Mobile Phone</type>
        <preferred>0</preferred>
        <value>563478653478</value>
      </contact>
      <contact>
        <type>Pager</type>
        <preferred>0</preferred>
        <value>7354635345</value>
      </contact>
      <contact>
        <notes>None</notes>
        <type>Home Email</type>
        <preferred>1</preferred>
        <value>johhny@smith.com</value>
        <comments>None</comments>
      </contact>
      <contact>
        <notes>None</notes>
        <type>Work Email</type>
        <preferred>0</preferred>
        <value>johhny@gmail.com</value>
        <comments>None</comments>
      </contact>
      <contact>
        <type>Home Phone</type>
        <preferred>1</preferred>
        <value>56537646365</value>
      </contact>
     </contact_list>
     </entity>

解决这个问题的最佳方法是什么?

谢谢

4

1 回答 1

1

这是一种方法(根据您的初始解决方案,我不以为然):

entities = doc.xpath("/entity_list/entity").map do |entity|
  {
    :id => entity.at_xpath("id").content.to_i,
    :first_name => entity.at_xpath("first_name").content,
    :last_name => entity.at_xpath("last_name").content,
    :preferred_email => entity.at_xpath("contact_list/contact[contains(type,'Email') and contains(preferred, '1')]/value").content,
    :manager => entity.at_xpath("manager").content
  }
end

编辑

为了挽救丢失的节点,您可以使用 ActiveSupport 的try方法,或者只是rescue nil在每行的末尾添加 a,例如:

:first_name => (entity.at_xpath("first_name").content rescue nil),

但最好使用辅助方法,例如:

def get_node_content(entity, xpath)
  node = entity.send(:at_xpath, xpath)
  node ? node.content : nil
end

然后你可以像这样使用它:

:first_name => get_node_content(entity, "first_name"),
于 2013-09-13T14:32:57.137 回答