2010-11-03 49 views
1

当检测类型我有以下格式的简单的XML文档:的Rails 3:解析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中没有“type”属性,所以使用Hash.from_xml只是将每个字段解析为一个字符串。我正在寻找的是某种字段类型的自动检测。我也看过Nokogiri,但不能输出为哈希。

什么是最简单和最有效的方式来实现这一目标?

非常感谢。

回答

2

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

#假设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” 来获得哈希值。

+0

谢谢你的回答。 – gjb 2010-11-04 09:59:41

1

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

如果你有一个散列,编写代码来遍历它并将这些值转换为你期望的类型并不难,或者只是在使用这些值的时候这样做。

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

1

请指定其作为XML属性:

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

或者只是使用适当的转换方法,红宝石,如果你知道你在什么接收:

hash[:strField].to_i 

有ISN”这将是一个非常神奇的方式来做到这一点。你可以尝试分析字符串中的内容,但是你可以很容易地得到一个字符串“1/2/1234”,它看起来像日期,但应该是一个字符串。

2

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

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