【问题标题】:Rails 3: Detecting types when parsing XMLRails 3:解析 XML 时检测类型
【发布时间】:2010-11-03 17:50:41
【问题描述】:

我有一个以下格式的简单 XML 文档:

<?xml version="1.0" encoding="utf-8"?>
<object>
  <strField>Foo</strField>
  <intField>1</intField>
  <dateField>2010-11-03</dateField>
  <boolField>true</boolField>
  <nilField></nilField>
</object>

我想把它解析成一个哈希值传递给 Model.create:

{:object => {
  :strField  => 'Foo',
  :intField  => 1,
  :dateField => Date.today,
  :boolField => true,
  :nilField  => nil }}

遗憾的是,XML 中没有“类型”属性,因此使用 Hash.from_xml 只是将每个字段解析为字符串。我正在寻找的是某种字段类型自动检测。我也看过 Nokogiri,但不能输出为 Hash。

实现这一目标的最简单、最有效的方法是什么?

非常感谢。

【问题讨论】:

    标签: ruby-on-rails ruby xml ruby-on-rails-3


    【解决方案1】:

    解决这个问题的正确方法是构建一个小的拉解析器。这是错误的方式:-)

    #假定xml持有xml

    def castValue(node)
      puts "Got #{node.name} with content #{node.content}"
      case node.name
      when "strField"
        return node.content
      when "intField"
        return node.content.to_i
      when "dateField"
        return Date.parse(node.content)
      when "boolField"
        case node.content
        when "true"
          return true
        else
          return false
        end
      when "nilField"
        return nil
      end
    end
    
    
    def to_hash xmlstring
      h = {}
      Nokogiri::XML.parse(xmlstring).root.children.each do |node|
        next if node.name == 'text'
        h[node.name] = castValue(node)
      end
      return h
    end
    

    从那里,您只需调用“h = to_hash myXMLstring”即可获取哈希。

    【讨论】:

      【解决方案2】:

      Rails 会在保存模型之前自动将字符串转换为正确的类型。就像你做的那样:ModelName.create( params[:model_name] )

      编辑:除非您的哈希值不是单独的列,例如你正在序列化它们。

      【讨论】:

        【解决方案3】:

        XML 不一定具有节点中值类型的指示符。在获取数据之前,您应该知道这一点,或者您的解析代码是。输出 XML 或电子表格的数据库通常知道数据的类型,它们会尝试为您提供一些定义,但无法保证它们所称的固定数字与 Ruby 所称的相匹配。因此,您仍然需要进行某种属性匹配/映射,以了解他们发送给您的内容。

        如果您有一个哈希,那么编写代码来遍历它并将值转换为您期望的类型并不难,或者只是在使用值时执行它。

        我总是使用 Nokogiri 直接解析 XML,然后在处理节点时设置值类型。

        【讨论】:

          【解决方案4】:

          要么将其指定为 XML 中的属性:

          <intField type="integer">101</intField>
          

          或者,如果你知道你收到了什么,或者只是在 Ruby 中使用适当的转换方法:

          hash[:strField].to_i
          

          没有什么神奇的方法可以做到这一点。您可以尝试分析字符串中的内容,但您可以轻松获得一个字符串“1/2/1234”,它看起来像一个日期,但应该是一个字符串。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-02-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多