2

Google Directions API から XML ドキュメントを解析しようとしています。

これは私がこれまでに得たものです:

x = Nokogiri::XML(GoogleDirections.new("48170", "48104").xml)
x.xpath("//DirectionsResponse//route//leg//step").each do |q|
  q.xpath("html_instructions").each do |h|
    puts h.inner_html
  end
end

出力は次のようになります。

Head <b>south</b> on <b>Hidden Pond Dr</b> toward <b>Ironwood Ct</b>
Turn <b>right</b> onto <b>N Territorial Rd</b>
Turn <b>left</b> onto <b>Gotfredson Rd</b>
...

出力を次のようにしたいと思います。

Turn <b>right</b> onto <b>N Territorial Rd</b>

問題は、Nokogiri が xml 内の html をエスケープしているようです

私はGoogleを信頼していますが、次のようにさらにサニタイズすることも良いと思います:

Turn right onto N Territorial Rd

しかし、生のxmlがなければ(おそらくサニタイズを使用して)できません。アイデア?

4

3 に答える 3

5

Google Directions API がインストールされていないため、XML にアクセスできませんが、XML を扱っていることを Nokogiri に伝えたことが問題の原因ではないかと強く疑っています。その結果、XML のようにエンコードされた HTML が返されます。

次のようなものを使用して HTML のエスケープを解除できます。

CGI::unescape_html('Head &lt;b&gt;south&lt;/b&gt; on &lt;b&gt;Hidden Pond Dr&lt;/b&gt; toward &lt;b&gt;Ironwood Ct&lt;/b&gt;')
=> "Head <b>south</b> on <b>Hidden Pond Dr</b> toward <b>Ironwood Ct</b>\n"

unescape_htmlのエイリアスunescapeHTMLです:

HTML エスケープされた文字列をエスケープ解除します
  CGI::unescapeHTML("使い方: foo "bar" <baz>")
     # => "使い方: foo \"bar\""

これについては、もう少し考えなければなりませんでした。それは私が遭遇したことですが、仕事で急いでいる間に私を逃れたものの1つでした. 修正は簡単です。コンテンツを取得するために間違った方法を使用しています。それ以外の:

puts h.inner_html

使用する:

puts h.text

私はこれを使用して証明しました:

require 'httpclient'
require 'nokogiri'

# This URL comes from: https://developers.google.com/maps/documentation/directions/#XML
url = 'http://maps.googleapis.com/maps/api/directions/xml?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false'
clnt = HTTPClient.new

doc = Nokogiri::XML(clnt.get_content(url))
doc.search('html_instructions').each do |html|
  puts html.text
end

どの出力:

Head <b>south</b> on <b>S Federal St</b> toward <b>W Van Buren St</b>
Turn <b>right</b> onto <b>W Congress Pkwy</b>
Continue onto <b>I-290 W</b>
[...]

違いはinner_html、ノードのコンテンツをデコードせずに直接読み取ることです。textあなたのためにそれをデコードします。textto_strあり、解析の楽しみのために Nokogiri::XML::Node の内部でinner_textエイリアス化されています。content

于 2013-04-19T23:54:41.887 に答える
1

ノードを CDATA でラップします。

def wrap_in_cdata(node)
    # Using Nokogiri::XML::Node#content instead of #inner_html (which
    # escapes HTML entities) so nested nodes will not work
    node.inner_html = node.document.create_cdata(node.content)
    node
end

Nokogiri::XML::Node#inner_htmlCDATA セクション以外の HTML エンティティをエスケープします。

fragment = Nokogiri::HTML.fragment "<div>Here is an unescaped string: <span>Turn left > right > straight & reach your destination.</span></div>"
puts fragment.inner_html
# <div>Here is an unescaped string: <span>Turn left &gt; right &gt; straight &amp; reach your destination.</span></div>


fragment.xpath(".//span").each {|node| node.inner_html = node.document.create_cdata(node.content) }
fragment.inner_html
# <div>Here is an unescaped string: <span>Turn left > right > straight & reach your destination.</span>\n</div>
于 2014-02-27T08:35:57.407 に答える