2010-11-22 5 views
0

J'essaie de lire du code XML récupéré à partir d'un service Web et de valider un attribut spécifique dans le fichier XML.Comment valider des attributs spécifiques en XML en utilisant REXML de Ruby?

C'est le XML jusqu'à la balise que je dois valider:

<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> 

Voici le code que j'ai jusqu'ici en utilisant REXML en Ruby:

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 

Je dois valider ExtractDateTimeFormatted est là et a une valeur valide pour cet attribut. Toute aide est grandement appréciée. :)


Lecture à partir d'un fichier XML local.

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 

Quand je lance ce code je reçois une erreur: « méthode non définie « à » pour # sur la ligne 21

Répondre

2

Êtes-vous lié à REXML ou pouvez-vous passer à Nokogiri Je recommande fortement Nokogiri sur? autres parseurs XML Ruby.

je devais ajouter suffisamment de balises XML pour rendre la validation de l'échantillon.

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 

Il y a une couple de choses en cours qui pourrait faire de cette harde r gérer qu'un simple fichier XML.

  1. Le code XML utilise des espaces de noms. Ils sont utiles, mais vous devez dire à l'analyseur comment les gérer. C'est pourquoi j'ai dû ajouter le deuxième paramètre à l'accesseur at().
  2. La valeur de date est dans un format souvent ambigu. Pour plusieurs jours de l'année, il est difficile de dire si c'est mm/jj/aaaa ou jj/mm/aaaa. Ici, aux États-Unis, nous supposons que c'est la première, mais l'Europe est la seconde. L'analyseur DateTime essaie de le comprendre, mais il se trompe souvent, surtout quand il pense qu'il est censé traiter un mois 22. Donc, plutôt que de le laisser deviner, je lui ai dit d'utiliser le format mm/jj/aaaa. Si une date ne correspond pas à ce format ou si les valeurs de la date sont hors limites, Ruby déclenchera une exception, vous devrez donc coder pour cela.

Voici un exemple de la façon de récupérer et analyser XML à la volée:

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 

Et un exemple de la façon de lire un fichier XML local et l'analyser:

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

Cette est génial mais j'ai un problème avec ça. Le XML est dynamique car chaque fois que je tape sur le service web, je vais avoir un nouvel horodatage. J'ai besoin de Nokogiri pour lire le xml de la mémoire. J'ai donc pris ma demande Savon et j'ai fait ceci: xml = request.to_s() – r3nrut

+0

Le problème que j'obtiens maintenant est: ContentService_Query.rb: 69: dans ' ': méthode non définie' at' f ou # (NoMethodError) – r3nrut

+0

Nokogiri s'en fout si le XML est statique ou dynamique, tant que le nom du tag reste le même qu'il sera toujours trouvé. –

Questions connexes