From: kou@... Date: 2018-09-04T05:12:45+00:00 Subject: [ruby-dev:50634] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode Issue #15057 has been updated by kou (Kouhei Sutou). ありがとうございます。確認できました。 現状の動きが変だという気持ちはわかるのですが、`Text#value`のドキュメントに > This ignores the 'raw' attribute setting と書いているので、`raw`のときもそうじゃないときも期待した挙動にするのは、互換性を維持したままではムリなんですよねぇ。 なので、`element1.text = element2.text`という使い方がよくないんですよねぇ。ただ、こう書けたほうがうれしいので、これに匹敵する使い勝手のAPIを考えておきます。 互換性は壊したくないので、現状ではatomutilでは次のように使ってもらいたいです。 ```diff diff --git a/lib/atomutil.rb b/lib/atomutil.rb index 9bb9e0c..6d9b985 100644 --- a/lib/atomutil.rb +++ b/lib/atomutil.rb @@ -523,7 +523,10 @@ module Atom element.add_attribute a end end - element.text = value.elem.text unless value.elem.text.nil? + text = value.elem.get_text + unless text.nil? + element.text = REXML::Text.new(text.to_s, true, nil, true) + end else if value.is_a?(REXML::Element) element.add_element value.deep_clone ``` ---------------------------------------- Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode https://bugs.ruby-lang.org/issues/15057#change-73871 * Author: rna (Ryosuke Nanba) * Status: Feedback * Priority: Normal * Assignee: kou (Kouhei Sutou) * Target version: * ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- `REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。 例: ~~~ require 'rexml/document' t = REXML::Text.new("< <", false, nil, false) t.to_s # => "&lt; <" t.value # => "< <" (expected: "< <") ~~~ `REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。 ~~~ # t = Text.new( "< & &s; russell", false, nil, false ) # t.value #-> "< & sean russell" ~~~ 非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。 -- https://bugs.ruby-lang.org/