2010-11-03 45 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])

編輯:除非你的散列值不是單獨的列,例如你在序列化它們。