ruby 为什么Nokogiri的to_xhtml从`name`创建新的`id`属性?

vxf3dgd4  于 2023-05-17  发布在  Ruby
关注(0)|答案(2)|浏览(227)

下面是一个例子:

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.谁来负责这件事,Nokogiri还是libxml2?
1.为什么会发生这种情况?(这是一个标准吗?))

  • 我能找到的最接近的是这个规范,它描述了如何可以idname属性设置为相同的值。*

1.如果希望在可能有<a name="foo">的输入上使用to_xhtml方法,有什么方法可以避免这种情况吗?

  • 出现此问题的原因是,我正在解析某个输入,其中一个元素具有id属性,而另一个单独的元素具有name属性,这两个属性发生冲突。*
bjg7j2ky

bjg7j2ky1#

it's a feature的libxml2在www.example.com中http://www.w3.org/TR/xhtml1/#h-4.10我们可以找到:
在XML中,片段标识符的类型为ID,每个元素只能有一个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
r7knjye2

r7knjye22#

也许您可以为这些元素添加其他id值,以防止libxml添加自己的值。

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

(显然,您需要确定如何为文档创建一个唯一的id值)。

相关问题