从文档中删除特定的名称空间



我有一个XML文档,它具有默认名称空间和根目录上定义的另一个前缀:

<r xmlns="a://foo" xmlns:b="a://bar" x="y"><!-- content not using b:* --></r>

使用Nokogiri,我已经浏览了文档,并使用b名称空间删除了元素和属性。现在我想修改文档,以便在输出时不具有b名称空间,即

<r xmlns="a://foo" x="y"><!-- content not using b:* --></r>

什么不工作

如果我使用remove_namespaces!,我甚至失去了默认的命名空间,这是我不想要的:

<r x="y"><!-- content not using b:* --></r>

我可以使用XPath选择名称空间,但Nokogiri::XML::Namespace不继承Node,也没有remove方法:

doc.at('//namespace::*[name()="b"]')
#=> #<Nokogiri::XML::Namespace:0x8104118c prefix="b" href="a://bar">
doc.at('//namespace::*[name()="b"]').remove
#=> NoMethodError: undefined method `remove' for #<Nokogiri::XML::Namespace:0x81025acc prefix="b" href="a://bar">
doc.xpath('//namespace::*[name()="b"]').remove; puts doc
#=> <r xmlns="a://foo" xmlns:b="a://bar" x="y"><!-- content not using b:* --></r>

根元素没有将命名空间声明作为可以被删除的属性:

doc.root.attributes
#=> {"x"=>#<Nokogiri::XML::Attr:0x8103dba4 name="x" value="y">} 

什么样的作品

由于文档很小,我将接受任何创建一个没有名称空间的文档新副本的解决方案,而不是改变现有的名称空间。

目前为止我得到的最好的解决方案是

doc.remove_namespaces!
doc.root.add_namespace(nil,'foo')
…但是这个核选项也会删除根目录的后代目录上的所有名称空间,这是不希望的。

在Nokogiri中,您可以将文档canonicalize,仅跳过名称空间声明,如下所示:

result = doc.canonicalize(nil,nil,1) do |o,_|
  !o.is_a?(Nokogiri::XML::Namespace) || o.href!="a://bar"
end

返回一个字符串(不是一个新文档)。如果你想要一个新的文档,你可以doc2 = Nokogiri.XML(result) .

请注意,虽然Nokogiri::XML::Node也有canonicalize方法,但它不接受块来决定是否保留项。你必须在文档本身调用这个。

第三个参数需要在规范化中包含注释。我不知道前两个选项做什么,除了运行时将分段故障,如果你传递一个1第二个参数。

但是,这个答案也会从文档中去掉空白。我不会接受这个

你可以选择根元素并删除它的属性,像这样:

doc.css('r')[0].attributes['xmlns:b'].remove

引用你自己的答案之一:)

使用文档作为HTML,

irb(main):001:0> require 'nokogiri'
=> true
irb(main):002:0> doc = '<r xmlns="foo" xmlns:b="bar" x="y"><!-- content not using b:* --></r>'
=> "<r xmlns="foo" xmlns:b="bar" x="y"><!-- content not using b:* --></r>"
irb(main):004:0> xml = Nokogiri::HTML(doc)
=> #<Nokogiri::HTML::Document:0x3fe4544e6268 name="document" children=[#<Nokogiri::XML::DTD:0x3fe4544e3158 name="html">, #<Nokogiri::XML::Element:0x3fe4544e2834 name="html" children=[#<Nokogiri::XML::Element:0x3fe4544e2410 name="body" children=[#<Nokogiri::XML::Element:0x3fe4544e2050 name="r" attributes=[#<Nokogiri::XML::Attr:0x3fe4544df01c name="xmlns" value="foo">, #<Nokogiri::XML::Attr:0x3fe4544dfcec name="xmlns:b" value="bar">, #<Nokogiri::XML::Attr:0x3fe4544dfd00 name="x" value="y">] children=[#<Nokogiri::XML::Comment:0x3fe4544df418 " content not using b:* ">]>]>]>]>
irb(main):005:0> xml.to_s
=> "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">n<html><body><r xmlns="foo" xmlns:b="bar" x="y"><!-- content not using b:* --></r></body></html>n"
irb(main):006:0> xml.css('r')[0].attributes['xmlns:b'].remove
=> #<Nokogiri::XML::Attr:0x3fe4544dfcec name="xmlns:b" value="bar">
irb(main):007:0> xml.to_s
=> "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">n<html><body><r xmlns="foo" x="y"><!-- content not using b:* --></r></body></html>n"
irb(main):008:0>

相关内容

  • 没有找到相关文章

最新更新