Wie wandle ich XML-Daten in einer hash in Rails?
Wie konvertiere ich eine XML-Körper zu einem hash in Ruby?
Ich habe eine XML-Stelle, die möchte ich analysieren, in eine hash -
<soap:Body>
<TimesInMyDAY>
<TIME_DATA>
<StartTime>2010-11-10T09:00:00</StartTime>
<EndTime>2010-11-10T09:20:00</EndTime>
</TIME_DATA>
<TIME_DATA>
<StartTime>2010-11-10T09:20:00</StartTime>
<EndTime>2010-11-10T09:40:00</EndTime>
</TIME_DATA>
<TIME_DATA>
<StartTime>2010-11-10T09:40:00</StartTime>
<EndTime>2010-11-10T10:00:00</EndTime>
</TIME_DATA>
<TIME_DATA>
<StartTime>2010-11-10T10:00:00</StartTime>
<EndTime>2010-11-10T10:20:00</EndTime>
</TIME_DATA>
<TIME_DATA>
<StartTime>2010-11-10T10:40:00</StartTime>
<EndTime>2010-11-10T11:00:00</EndTime>
</TIME_DATA>
</TimesInMyDAY>
</soap:Body>
Möchte ich es konvertieren in einen hash wie dieser:
{ :times_in_my_day => {
:time_data = > [
{:start_time=>"2010-11-10T09:00:00", :end_time => "2010-11-10T09:20:00" },
{:start_time=>"2010-11-10T09:20:00", :end_time => "2010-11-10T09:40:00" },
{:start_time=>"2010-11-10T09:40:00", :end_time => "2010-11-10T10:00:00" },
{:start_time=>"2010-11-10T10:00:00", :end_time => "2010-11-10T10:20:00" },
{:start_time=>"2010-11-10T10:40:00", :end_time => "2010-11-10T11:00:00" }
]
}
}
Idealerweise werden die tags umgewandelt werden snake_case Symbole und zum Schlüssel in dem hash.
Auch, die datetimes vermissen Ihre Zeitzone offsets. Sie sind in der lokalen Zeitzone (nicht UTC). So würde ich mag, um zu analysieren es, um zu zeigen, das lokale offset und dann konvertieren Sie die xml datetime String in ein Schienen-DateTime-Objekte. Das resultierende array wäre so etwas wie:
{ :times_in_my_day => {
:time_data = > [
{:start_time=>Wed Nov 10 09:00:00 -0800 2010, :end_time => Wed Nov 10 9:20:00 -0800 2010 },
{:start_time=>Wed Nov 10 09:20:00 -0800 2010, :end_time => Wed Nov 10 9:40:00 -0800 2010 },
{:start_time=>Wed Nov 10 09:40:00 -0800 2010, :end_time => Wed Nov 10 10:00:00 -0800 2010 },
{:start_time=>Wed Nov 10 10:00:00 -0800 2010, :end_time => Wed Nov 10 10:20:00 -0800 2010 },
{:start_time=>Wed Nov 10 10:40:00 -0800 2010, :end_time => Wed Nov 10 11:00:00 -0800 2010 }
]
}
}
War ich in der Lage, konvertieren Sie eine einzelne datetime mit der parse
und in_time_zone
Methoden auf diese Weise:
Time.parse(xml_datetime).in_time_zone(current_user.time_zone)
Aber ich bin mir nicht ganz sicher der beste Weg, um eine Analyse der Zeiten, während die Umwandlung der XML-Datei in ein hash.
Ich würde schätzen jede Beratung. Danke!
Bearbeiten
Den code für die Konvertierung des datetime-string in eine Rails-DateTime-Objekt falsch ist. Wird zum Parsen der xml-datetime-Zeichenfolge, um die system-Zeitzone-offset und dann zu konvertieren, dass die Zeit für die user-Zeitzone. Der richtige code lautet:
Time.zone.parse(xml_datetime)
Wenn der Benutzer hat eine andere Zeitzone, andere als im system, dadurch wird die Zeitzone des Benutzers offset zur ursprünglichen datetime string. Gibt es einen Railscast zum aktivieren von Benutzer-Zeitzone-Einstellungen hier: http://railscasts.com/episodes/106-time-zones-in-rails-2-1.
Time.zone.parse(xml_datetime)
<- Super! danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich XML::Simple Perl, da das analysieren von XML mit Hilfe von Perl war ein PITA.
Wenn ich wechselte zu Rubin landete ich mit Nokogiri, und fand es sehr einfach zu bedienen für das Parsen von HTML und XML. Es ist so einfach, dass ich denke, dass in Bezug auf CSS-oder XPath-Selektoren und verpassen Sie nicht eine XML-zu-hash-Konverter.
mit dem Ausgang suchen, wie:
Zeit Werte werden bewusst analysiert in DateTime und Zeit-Objekte zu zeigen, die entweder verwendet werden könnte.
doc.to_hash
?. Ich habe einen Fall, wo die XML-Quelle ist tief geschachtelt, so fragte sich, ob es einen eleganten Weg dies zu tun, ohne zu schreiben eine Menge von Iteratoren für jede Ebene.result = Hash.from_xml(xml_source)
, aber nicht konvertieren die tags snake_case Symbole 🙁:start_time => Time.parse(start_time)
und:end_time => DateTime.parse(end_time)
... meinst du mit Time-und DateTime-anders? Nur die überprüfung, ob es einen Grund für den Unterschied.//
so, dass es immerstart_time = t.at('StartTime').inner_text
... ich gotta get verwendet, um den xpath-Selektoren! Noch nicht intuitiv für mich.Hash.from_xml(xml)
einfache Möglichkeit, dies zu lösen. Seine activesupport-MethodeActiveSupport fügt eine
Hash.from_xml
, die nicht die Umwandlung in einem einzigen Aufruf. Beschrieben in einer anderen Frage: https://stackoverflow.com/a/7488299/937595Beispiel:
Die ursprüngliche Frage wurde vor einiger Zeit gefragt, aber ich habe eine einfachere Lösung als die Verwendung von Nokogiri und die Suche nach bestimmten Namen in der XML.
Nori.parse(your_xml)
analysiert die XML-Datei in ein hash und die Tasten haben die gleichen Namen wie Ihre XML-Elemente.Wenn es Ihnen nichts ausmacht mit einem Edelstein, crack hat einen ziemlich guten job bei dieser.
Crack funktioniert die XML-hash-Verarbeitung, dann können Sie mit einer Schleife über die daraus resultierenden hash zu normalisieren, die datetimes.
Bearbeiten
Mit REXML, Sie könnten versuchen, die folgenden (sollte in der Nähe zu arbeiten, aber ich habe keinen Zugriff auf ein terminal, so müssen Sie möglicherweise einige Optimierungen):
Natürlich, dies setzt Voraus, die Struktur ist IMMER die gleiche, und dass das Beispiel, das Sie geschrieben war nicht gekünstelt Einfachheit halber (als Beispiele sind oft).
2010-11-10T09:00:00
sich inWed Nov 10 01:00:00 -0800 2010
wenn ich wirklich wollteWed Nov 10 09:00:00 -0800 2010
🙁doc = REXML::XPath.first(REXML::Document.new(xml), "//soap:Body/TimesInMyDAY").text
. Der Fehler istREXML::UndefinedNamespaceException: Undefined prefix soap found