嘗試處理來自名爲TeleForm的應用程序的一些XML。這是表單掃描軟件,它抓取數據並將其放入XML中。這是XMLRails Hash.from_xml沒有給出預期的結果
<?xml version="1.0" encoding="ISO-8859-1"?>
<Records>
<Record>
<Field id="ImageFilename" type="string" length="14"><Value>00000022000000</Value></Field>
<Field id="Criterion_1" type="number" length="2"><Value>3</Value></Field>
<Field id="Withdrew" type="string" length="1"></Field>
</Record>
<Record>
<Field id="ImageFilename" type="string" length="14"><Value>00000022000001</Value></Field>
<Field id="Criterion_1" type="number" length="2"><Value>3</Value></Field>
<Field id="Withdrew" type="string" length="1"></Field>
</Record>
</Records>
我在其他的系統處理了這個,可能使用我們寫了一個自定義分析器的一個片段。我認爲這在Rails中沒有問題,但我錯了。
與Hash.from_xml或引入nokogiri解析這不給我我希望的結果,我得到:
{"Records"=>{"Record"=>[{"Field"=>["", {"id"=>"Criterion_1", "type"=>"number", "length"=>"2", "Value"=>"3"}, ""]},
{"Field"=>["", {"id"=>"Criterion_1", "type"=>"number", "length"=>"2", "Value"=>"3"}, ""]}]}}
這個花費了太多的時間後,我發現,如果我GSUB出來的類型和長度屬性,我得到我的預期(即使它是錯誤的!我只在第一個記錄節點上刪除)。
{"Records"=>{"Record"=>[{"Field"=>[{"id"=>"ImageFilename", "Value"=>"00000022000000"},
{"id"=>"Criterion_1", "type"=>"number", "length"=>"2", "Value"=>"3"}, {"id"=>"Withdrew"}]},
{"Field"=>["", {"id"=>"Criterion_1", "type"=>"number", "length"=>"2", "Value"=>"3"}, ""]}]}}
並無在XML樣樣精通,我認爲XML的這種風格的使用類型和長度屬性正試圖轉換爲數據類型。在這種情況下,我可以理解爲什麼「Withdrew」屬性顯示爲空,但不明白爲什麼「ImageFilename」是空的 - 它是一個14個字符的字符串。
我已經用gsub解決了這個問題,但這是無效的XML嗎?添加一個DTD(TeleForm應該提供的)會給我不同的結果嗎?
編輯
我會提供了一個可能的答案,以我自己的問題與一些代碼編輯。代碼如下一些在一個答案,我也從馬克托馬斯接收功能,但我決定不引入nokogiri,原因如下:
- XML是一致的,送花兒給人包含相同的代碼(/唱片/錄音/字段)和屬性。
- 在每個XML文件中可能有幾百條記錄,Nokogiri似乎有點慢,只有26條記錄
- 我想出瞭如何讓Hash.from_xml給我我所期望的(不喜歡type =「string」 ,但只使用哈希值來填充類。
的XML的擴展版本,一個完整的記錄
<?xml version="1.0" encoding="ISO-8859-1"?>
<Records>
<Record>
<Field id="ImageFilename" type="string" length="14"><Value>00000022000000</Value></Field>
<Field id="DocID" type="string" length="15"><Value>731192AIINSC</Value></Field>
<Field id="FormID" type="string" length="6"><Value>AIINSC</Value></Field>
<Field id="Availability" type="string" length="18"><Value>M T W H F S</Value></Field>
<Field id="Criterion_1" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_2" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_3" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_4" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_5" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_6" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_7" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_8" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_9" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_10" type="number" length="2"><Value>3</Value></Field>
<Field id="Criterion_11" type="number" length="2"><Value>0</Value></Field>
<Field id="Criterion_12" type="number" length="2"><Value>0</Value></Field>
<Field id="Criterion_13" type="number" length="2"><Value>0</Value></Field>
<Field id="Criterion_14" type="number" length="2"><Value>0</Value></Field>
<Field id="Criterion_15" type="number" length="2"><Value>0</Value></Field>
<Field id="DayTraining" type="string" length="1"><Value>Y</Value></Field>
<Field id="SaturdayTraining" type="string" length="1"></Field>
<Field id="CitizenStageID" type="string" length="12"><Value>731192</Value></Field>
<Field id="NoShow" type="string" length="1"></Field>
<Field id="NightTraining" type="string" length="1"></Field>
<Field id="Withdrew" type="string" length="1"></Field>
<Field id="JobStageID" type="string" length="12"><Value>2292</Value></Field>
<Field id="DirectHire" type="string" length="1"></Field>
</Record>
</Records>
我只與工作流的原型試驗,以取代寫在4D老化系統和Active4D。這個區域處理TeleForm s數據作爲批處理操作來執行,它仍然可以恢復到這種狀態。我只是想在新的Rails實現中合併一些舊的可行的概念。 XML文件位於共享服務器上,可能必須將其移至Web根目錄,然後將某些觸發器設置爲處理文件。
我仍然處於定義階段,但我的模塊/類來處理InterviewForm看起來像這樣,可能會改變(很少有錯誤陷阱,仍然試圖進入測試,我的Ruby不如它應該好):
module Teleform::InterviewForm
class Form < Prawn::Document
# Not relevant to this question, but this class generates the forms from a Fillable PDF template and
# relavant Model(s) data.
# These forms, when completed are what is processsed by TeleForms and produces the xml.
end
class RateForms
attr_accessor :records, :results
def initialize(xml_path)
fields = []
xml = File.read(xml_path)
# Hash.from_xml does not like a type of "string"
hash = Hash.from_xml(xml.gsub(/type="string"/,'type="text"'))
hash["Records"]["Record"].each do |record|
#extract the field form each record
fields << record["Field"]
end
@records = []
fields.each do |field|
#build the records for the form
@records << Record.new(field)
end
@results = rate_records
end
def rate_records
# not relevant to the qustions but this is where the data is processed and a bunch of stuff takes place
return "Any errors"
end
end
class Record
attr_accessor(*[:image_filename, :doc_id, :form_id, :availability, :criterion_1, :criterion_2,
:criterion_3, :criterion_4, :criterion_5, :criterion_6, :criterion_7, :criterion_8,
:criterion_9, :criterion_10, :criterion_11, :criterion_12, :criterion_13, :criterion_14, :criterion_15,
:day_training, :saturday_training, :citizen_stage_id, :no_show, :night_training, :withdrew, :job_stage_id, :direct_hire])
def initialize(fields)
fields.each do |field|
if field["type"] == "number"
try("#{field["id"].underscore.to_sym}=", field["Value"].to_i)
else
try("#{field["id"].underscore.to_sym}=", field["Value"])
end
end
end
end
end
想要什麼數據,您解壓? – 2013-02-15 23:07:02
真的只是記錄的id和價值。我將長度屬性名稱更改爲tf_length以獲取字符串以顯示我然後只是遍歷數組/ has並生成散列數組。 – appleII717 2013-02-15 23:27:42
等待,每個記錄有3個ID和2個值。你想要哪一個? – 2013-02-16 00:44:23