0

Web サービスから取得した XML を読み取って、XML 内の特定の属性を検証しようとしています。

これは、検証する必要があるタグまでの XML です。

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

これまでに Ruby で REXML を使用したコードは次のとおりです。

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

ExtractDateTimeFormatted が存在し、その属性に有効な値があることを検証する必要があります。どんな助けでも大歓迎です。:)


ローカル xml ファイルから読み取ります。

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

このコードを実行すると、次のエラーが表示されます:「未定義のメソッド 'at' for # 21 行目

4

1 に答える 1

2

REXML に縛られていますか、それとも Nokogiri に切り替えることができます? 他の Ruby XML パーサーよりも Nokogiri を強くお勧めします。

サンプルを検証するには、十分な数の XML タグを追加する必要がありました。

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

これを単純な XML ファイルよりも扱いにくくしている可能性があることがいくつかあります。

  1. XML は名前空間を使用しています。それらは便利ですが、パーサーにそれらの処理方法を伝える必要があります。そのため、2 番目のパラメーターをat()アクセサーに追加する必要がありました。
  2. 日付の値は、しばしばあいまいな形式になっています。1 年の多くの日は、mm/dd/yyyy なのか dd/mm/yyyy なのかを判断するのが困難です。ここアメリカでは最初だと思いますが、ヨーロッパは 2 番目です。DateTime パーサーはそれを理解しようとしますが、特に 22 の月を処理することになっていると考えると、しばしば間違ってしまいます。そのため、推測させるのではなく、mm/dd/yyyy 形式を使用するように指示しました。日付がその形式に一致しない場合、または日付の値が範囲外の場合、Ruby は例外を発生させるため、そのためのコードを作成する必要があります。

これは、XML をオンザフライで取得して解析する方法の例です。

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

ローカル XML ファイルを読み取って解析する方法の例:

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>
于 2010-11-22T17:21:17.647 に答える