3

次のコードを検討してください。

require 'nokogiri' # v1.5.2
doc = Nokogiri.XML('<body><a name="foo">ick</a></body>')

puts doc.to_html
#=> <body><a name="foo">ick</a></body>

puts doc.to_xml
#=> <?xml version="1.0"?>
#=> <body>
#=>   <a name="foo">ick</a>
#=> </body>

 puts doc.to_xhtml
 #=> <body>
 #=>   <a name="foo" id="foo">ick</a>
 #=> </body>

作成された新しいid属性に注意してください。

  1. これはノコギリとlibxml2のどちらが責任を負っていますか?
  2. なぜこれが起こるのですか?(これは標準を強制していますか?)
    私が見つけることができる最も近いものは、同じ値を持つand属性の両方配置する方法を説明するこの仕様です。idname
  3. to_xhtml可能性のある入力でメソッドを使用したい場合、これを回避する方法はあります<a name="foo">か?

この問題は、ある要素の属性と競合idする属性を持つ別の要素で解析している入力があるために発生します。name

4

2 に答える 2

2

どうやらそれはlibxml2の機能です。http://www.w3.org/TR/xhtml1/#h-4.10には、次のものがあります。

XMLでは、フラグメント識別子はタイプであり、要素ごとIDにタイプの属性は1つだけです。IDしたがって、XHTML 1.0では、id属性はタイプとして定義されていますID。XHTML 1.0ドキュメントが適切に構造化されたXMLドキュメントであることを保証するために、XHTML 1.0ドキュメントは、上記の要素でフラグメント識別子を定義するときに属性を使用する必要があります。id
[...]
XHTML 1.0では、nameこれらの要素の属性は正式に非推奨になり、XHTMLの後続のバージョンで削除されることに注意してください。

私が思いついた最高の「回避策」は次のとおりです。

# Destroy all <a name="..."> elements, replacing with children
# if another element with a conflicting id already exists in the document
doc.xpath('//a[@name][not(@id)][not(@href)]').each do |a|
  a.replace(a.children) if doc.at_css("##{a['name']}")
end
于 2012-04-20T20:20:04.890 に答える
1

おそらく、これらの要素に他のid値を追加して、libxml が独自の値を追加するのを防ぐことができます。

doc.xpath('//a[@name and not(@id)]').each do |n|
  n['id'] = n['name'] + 'some_suffix'
end

(明らかに、ドキュメントに固有の値を作成する方法を決定する必要がありidます)。

于 2012-04-20T21:23:04.797 に答える