2010-11-22 12 views
0

Ich versuche, etwas XML zu lesen, das ich von einem Webdienst abgerufen habe, und validiere ein bestimmtes Attribut innerhalb des XML.Wie validiere ich bestimmte Attribute in XML mit REXML von Ruby?

Dies ist der XML mit dem Tag, die ich bestätigen müssen:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s:Body> 
    <QueryResponse xmlns="http://tempuri.org/"> 
     <QueryResult xmlns:a="http://schemas.datacontract.org/2004/07/Entity" 
     xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <a:Navigation i:nil="true" /> 
     <a:SearchResult> 
      <a:EntityList> 
      <a:BaseEntity i:type="a:Product"> 
       <a:ExtractDateTime>1290398428</a:ExtractDateTime> 
       <a:ExtractDateTimeFormatted>11/22/2010 
       04:00:28</a:ExtractDateTimeFormatted> 

Hier ist der Code ist habe ich bisher REXML in Ruby mit:

require 'xmlsimple' 
require 'rexml/document' 
require 'rexml/streamlistener' 
include REXML 


class Listener 
include StreamListener 

xmlfile = File.new("rbxml_CS_Query.xml") 
xmldoc = Document.new(xmlfile) 

# Now get the root element 
root = xmldoc.root 
puts root.attributes["a:EntityList"] 

# This will output the date/time of the query response 
xmldoc.elements.each("a:BaseEntity"){ 
    |e| puts e.attributes["a:ExtractDateTimeFormatted"] 
} 

end 

Ich muss bestätigen, dass ExtractDateTimeFormatted ist da und hat einen gültigen Wert für dieses Attribut. Jede Hilfe wird sehr geschätzt. :)


Lesen von lokalen XML-Datei.

File.open('temp.xml', 'w') { |f| 
    f.puts request 
    f.close 
    } 

    xml = File.read('temp.xml') 

    doc = Nokogiri::XML::Reader(xml) 
    extract_date_time_formatted = doc.at(
    '//a:ExtractDateTimeFormatted', 
    'a' => 'http://schemas.datacontract.org/2004/07/Entity' 
).inner_text 
    show = DateTime.strptime(extract_date_time_formatted, '%m/%d/%Y') 
    puts show 

Wenn ich diesen Code ausführen bekomme ich eine Fehlermeldung: „nicht definierte Methode 'at' für # on line 21

Antwort

2

Sie gebunden sind, um REXML oder können Sie wechseln zu Nokogiri I Nokogiri über das empfehlen? anderer Ruby-XML-Parser.

hatte ich genug XML-Tags hinzufügen, um die Probe zu validieren zu machen.

require 'date' 
require 'nokogiri' 

xml = %q{<?xml version="1.0"?> 
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
     <s:Body> 
      <QueryResponse xmlns="http://tempuri.org/"> 
       <QueryResult xmlns:a="http://schemas.datacontract.org/2004/07/Entity" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
        <a:Navigation i:nil="true"/> 
        <a:SearchResult> 
         <a:EntityList> 
          <a:BaseEntity i:type="a:Product"> 
           <a:ExtractDateTime>1290398428</a:ExtractDateTime> 
           <a:ExtractDateTimeFormatted>11/22/2010</a:ExtractDateTimeFormatted> 
          </a:BaseEntity> 
         </a:EntityList> 
        </a:SearchResult> 
       </QueryResult> 
      </QueryResponse> 
     </s:Body> 
    </s:Envelope> 
} 

doc = Nokogiri::XML(xml) 

extract_date_time_formatted = doc.at(
    '//a:ExtractDateTimeFormatted', 
    'a' => 'http://schemas.datacontract.org/2004/07/Entity' 
).inner_text 
puts DateTime.strptime(extract_date_time_formatted, '%m/%d/%Y') 
# >> 2010-11-22T00:00:00+00:00 

Es gibt ein paar Dinge, die ich, dass diese harde machen könnte r als eine einfache XML-Datei zu behandeln.

  1. Das XML verwendet Namespaces. Sie sind nützlich, aber Sie müssen dem Parser sagen, wie er damit umgehen soll. Deshalb musste ich den zweiten Parameter zum at() Accessor hinzufügen.
  2. Der Datumswert ist in einem Format, das oft nicht eindeutig ist. Für viele Tage des Jahres ist es schwer zu sagen, ob es mm/TT/JJJJ oder TT/MM/JJJJ ist. Hier in den USA nehmen wir an, es ist das erste, aber Europa ist das zweite. Der DateTime-Parser versucht, es herauszufinden, aber oft wird es falsch verstanden, besonders wenn es denkt, dass es mit einem Monat 22 zu tun hat. Also, anstatt es raten zu lassen, habe ich ihm gesagt, das Format mm/dd/yyyy zu verwenden. Wenn ein Datum nicht mit diesem Format übereinstimmt oder die Werte des Datums außerhalb des gültigen Bereichs liegen, wird Ruby eine Ausnahme auslösen. Sie müssen also dafür codieren.

Dies ist ein Beispiel dafür, wie XML on the fly abrufen und analysieren:

require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::XML(open('http://java.sun.com/developer/earlyAccess/xml/examples/samples/book-order.xml')) 
puts doc.class 
puts doc.to_xml 

und ein Beispiel dafür, wie eine lokale XML-Datei zu lesen und analysieren:

require 'nokogiri' 

doc = Nokogiri::XML(File.read('test.xml')) 
puts doc.to_xml 
# >> <?xml version="1.0"?> 
# >> <root xmlns:foo="bar"> 
# >> <bar xmlns:hello="world"/> 
# >> </root> 
+0

Diese ist toll, aber ich habe ein Problem damit. Das XML ist dynamisch, da ich jedes Mal, wenn ich den Web-Service betrete, einen neuen Zeit-/Datumsstempel habe. Ich brauche Nokogiri, um das xml aus dem Speicher zu lesen. Also nahm ich meine Savon Anfrage und tat dies: xml = request.to_s() – r3nrut

+0

Das Problem, das ich jetzt bekomme, ist: ContentService_Query.rb: 69: in ' ': undefined Methode' at' f oder # (NoMethodError) – r3nrut

+0

Nokogiri ist es egal, ob der XML-Code statisch oder dynamisch ist, solange der Tag-Name gleich bleibt und trotzdem gefunden wird. –