質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SOAP

SOAP(Simple Object Access Protocol)はウェブサービス実装においての構造化された情報をやり取りするためのプロトコル規定です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

2861閲覧

SOAPのレスポンスxmlでparseができない。Ruby on Rails. Nokogiri.

el__ninja

総合スコア12

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SOAP

SOAP(Simple Object Access Protocol)はウェブサービス実装においての構造化された情報をやり取りするためのプロトコル規定です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2017/10/11 22:24

SAOP通信にて得たxmlがうまくパースできません

ruby

1@doc = Nokogiri::XML(response.body) 2puts @doc

以下レスポンスxmlです。

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 3 <S:Body> 4 <ELtest xmlns="http://www.xxx.com" xmlns:ns2="http://www.xxx.com" Version="1.0"> 5 <Success/> 6 <eltests> 7 <eltest> 8 <Date End="2017-10-11" Start="2017-10-01" Status="Close"/> 9 <Date End="2017-10-15" Start="2017-10-12" Status="Open"/> 10 <Date End="2017-10-16" Start="2017-10-16" Status="Close"/> 11 <Date End="2017-10-20" Start="2017-10-17" Status="Open"/> 12 <Price total="4000" End="2017-10-12" Start="2017-10-12"/> 13 <Price total="6000" End="2017-10-13" Start="2017-10-13"/> 14 <Price total="6000" End="2017-10-14" Start="2017-10-14"/> 15 <Price total="4000" End="2017-10-15" Start="2017-10-15"/> 16 <Price total="4000" End="2017-10-17" Start="2017-10-17"/> 17 <Price total="4000" End="2017-10-18" Start="2017-10-18"/> 18 <Price total="4000" End="2017-10-19" Start="2017-10-19"/> 19 <Price total="6000" End="2017-10-20" Start="2017-10-20"/> 20 </eltest> 21 </eltests> 22 </ELtest> 23 </S:Body> 24</S:Envelope>

このDate EndやPrice totalの値をxpathで取得しようとしてもうまくいきません。
以下のように指定すると

ruby

1puts @doc.xpath("//S:Body")[0].children[0].children[1].children[0]

レスポンス

xml

1<eltests> 2 <eltest> 3 <Date End="2017-10-11" Start="2017-10-01" Status="Close"/> 4 <Date End="2017-10-15" Start="2017-10-12" Status="Open"/> 5 <Date End="2017-10-16" Start="2017-10-16" Status="Close"/> 6 <Date End="2017-10-20" Start="2017-10-17" Status="Open"/> 7 <Price total="4000" End="2017-10-12" Start="2017-10-12"/> 8 <Price total="6000" End="2017-10-13" Start="2017-10-13"/> 9 <Price total="6000" End="2017-10-14" Start="2017-10-14"/> 10 <Price total="4000" End="2017-10-15" Start="2017-10-15"/> 11 <Price total="4000" End="2017-10-17" Start="2017-10-17"/> 12 <Price total="4000" End="2017-10-18" Start="2017-10-18"/> 13 <Price total="4000" End="2017-10-19" Start="2017-10-19"/> 14 <Price total="6000" End="2017-10-20" Start="2017-10-20"/> 15 </eltest> 16 </eltests>

上記のようなところまでは絞りこめるのですが、
欲しいデータ部分にたどり着きません。

どなたかパースのやり方わかりますでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

XMLにnamespaceが定義されているので取得が大変になっています。
もし名前の衝突等がなく名前空間を無視できるのであれば、いっそのこと削除してしまってもよいかもしれません。
そうすると下記のように書くことができるかと思います。

ruby

1require 'nokogiri' 2 3### some process here ### 4 5doc = Nokogiri::XML(response.body) 6doc.remove_namespaces! 7 8doc.xpath('//eltest').each do |eltest| 9 eltest.children.each do |node| 10 if node.element? then 11 str = node.name 12 node.attribute_nodes.each do |attr| 13 str += ": " + attr.name + " => " + attr.value 14 end 15 puts str 16 end 17 end 18end

出力結果は下記のような感じです。
ここまでくればあとは加工だけなので、処理の実装はできるものと思います。

Date: End => 2017-10-11: Start => 2017-10-01: Status => Close Date: End => 2017-10-15: Start => 2017-10-12: Status => Open Date: End => 2017-10-16: Start => 2017-10-16: Status => Close Date: End => 2017-10-20: Start => 2017-10-17: Status => Open Price: total => 4000: End => 2017-10-12: Start => 2017-10-12 Price: total => 6000: End => 2017-10-13: Start => 2017-10-13 Price: total => 6000: End => 2017-10-14: Start => 2017-10-14 Price: total => 4000: End => 2017-10-15: Start => 2017-10-15 Price: total => 4000: End => 2017-10-17: Start => 2017-10-17 Price: total => 4000: End => 2017-10-18: Start => 2017-10-18 Price: total => 4000: End => 2017-10-19: Start => 2017-10-19 Price: total => 6000: End => 2017-10-20: Start => 2017-10-20

投稿2017/10/12 00:56

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

eltestsから下の階層は、以下のようになっているようですから、DateやPriceはeltestsの孫エレメント(childrenのchildren)に当たります。

eltests

''+- eltest
'''''' +- Date
'''''' +- Price

eltestsが、「puts @doc.xpath("//S:Body")[0].children[0].children[1].children[0]」で得られているのですから、
その子エレメントであるeltestは、「puts @doc.xpath("//S:Body")[0].children[0].children[1].children[0].children[0]」で得られます。(パスの最後に".children[0]"が追加されています)

更に、その子のエレメントであるDateやPriceは「puts @doc.xpath("//S:Body")[0].children[0].children[1].children[0].children[0].children[n]」で得られます。
(更に、パスの最後に".children[n]"が追加されています。nは、0~11の整数で、0~3でDate、4~11でPriceの各エレメントが得られるはずです)

投稿2017/10/12 00:36

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問