Нокогири и Кодировка - PullRequest
1 голос
/ 22 июня 2011

Пожалуйста, рассмотрите следующий SAX Parser, построенный с использованием Nokogiri.

#encoding: UTF-8

require 'nokogiri'

class MyParser < Nokogiri::XML::SAX::Document

  def initialize(&callback)
    @callback = callback
    @buffer = ""
    @parser = Nokogiri::XML::SAX::PushParser.new(self, "UTF-8")
    @elem = nil
    @doc  ||= Nokogiri::XML::Document.new
    super()
  end

  def push(data)
    @parser << data
  end

  def start_element(name, attributes = [])
    @elem = Nokogiri::XML::Element.new(name, @doc)
    attributes.each do |k, v|
      @elem.set_attribute(k, v)
    end
  end

  def end_element(name)
    clear_characters_buffer
    @callback.call(@elem) 
  end

  def clear_characters_buffer
    if @buffer && @elem
      @buffer.strip!
      @elem.add_child(Nokogiri::XML::Text.new(@buffer, @doc)) unless @buffer.empty?
      @buffer = nil # empty the buffer
    end
  end

  def characters(string)
    @buffer ||= ""
    @buffer << string 
  end

end


xml =<<-EOXML
<entry>
<title>Appel à témoins pour émission de TV sur les jobs d'été</title>
<summary type="text">Je laisse la parole à Caroline, journaliste, qui recherche des étudiants pour une émission sur les jobs d'été à la rentrée.</summary>
<link rel="alternate" type="text/html" href="http://www.jobetudiant.net/blog/index.php?2011/04/29/573-appel-tmoins-pour-mission-de-tv-sur-les-jobs-d-t" title="Appel à témoins pour émission de TV sur les jobs d'été"/>
EOXML

p = MyParser.new() do |node|
  puts node.to_xml(:encoding => "UTF-8")
end

p.push(xml)

##
# Output :
## 
# $ ruby encoding-bug.rb 
# <title>Appel à témoins pour émission de TV sur les jobs d'été</title>
# <summary type="text">Je laisse la parole à Caroline, journaliste, qui recherche des étudiants pour une émission sur les jobs d'été à la rentrée.</summary>
# <link rel="alternate" type="text/html" href="http://www.jobetudiant.net/blog/index.php?2011/04/29/573-appel-tmoins-pour-mission-de-tv-sur-les-jobs-d-t" title="Appel &#xE0; t&#xE9;moins pour &#xE9;mission de TV sur les jobs d'&#xE9;t&#xE9;"/>

## 
# Expected :
## 
# $ ruby encoding-bug.rb 
# <title>Appel à témoins pour émission de TV sur les jobs d'été</title>
# <summary type="text">Je laisse la parole à Caroline, journaliste, qui recherche des étudiants pour une émission sur les jobs d'été à la rentrée.</summary>
# <link rel="alternate" type="text/html" href="http://www.jobetudiant.net/blog/index.php?2011/04/29/573-appel-tmoins-pour-mission-de-tv-sur-les-jobs-d-t" title="Appel à témoins pour émission de TV sur les jobs d'été"/>

Как вы можете видеть, он снабжается строкой UTF8.Синтаксический анализатор SAX отлично справляется с запуском правильных событий с правильными строками, но когда я пытаюсь снова вставить это в документ, по какой-то причине он неправильно сериализует атрибуты, перекодируя их в UTF-8.Кто-нибудь знает, что происходит?

1 Ответ

0 голосов
/ 22 июня 2011

Это HTML-экранирование значений атрибутов. Если вы измените свой пример на

xml =<<-EOXML
<entry title="jobs d'été">
jobs d'été
</entry>
EOXML

понятнее:

<entry title="jobs d'&#xE9;t&#xE9;">jobs d'été</entry>

Вы можете конвертировать их обратно, как это

require 'cgi'
p = MyParser.new() do |node|
  puts CGI.unescapeHTML(node.to_xml(:encoding => "UTF-8"))
end

, что дает

<entry title="jobs d'été">jobs d'été</entry>
...