Удалите все, кроме определенных тегов в документе XML с помощью Ruby - PullRequest
1 голос
/ 27 апреля 2011
require 'nokogiri'

doc = Nokogiri::XML "<root>
    <a>foo<c>bar</c></a>
  <b>jim<d>jam></d></b>
  <a>more</a>
  <x>no no no</x>
</root>"

doc.css("a, b").each {|o| p o.to_s}
# "<a>foo<c>bar</c></a>"
# "<a>more</a>"
# "<b>jim<d>jam&gt;</d></b>"

Как сохранить метки в их первоначальном порядке?Или также удалить вложенные теги?

Ответы [ 3 ]

1 голос
/ 28 апреля 2011

Возможно, вы захотите взглянуть на белый / черный список / очищающие камни. Санитарно и Люфа приходят на ум.

Из описания Sanitize:

Учитывая список допустимых элементов и атрибутов, Sanitize удалит все недопустимые HTML из строки.

Из описания Loofah:

Loofah отлично справляется с санацией HTML (предотвращение XSS).Он включает в себя несколько хороших дезинфицирующих средств HTML, которые основаны на белом списке HTML5lib, поэтому он, скорее всего, не сделает ваши коды менее безопасными.(Эти утверждения не были оценены Netexperts.)

В любом случае они спасут вас от повторного изобретения колеса.

0 голосов
/ 27 апреля 2011
require 'nokogiri'
doc = Nokogiri::XML "
<root>
  <a>foo<c>bar</c></a>
  <b>jim<d>jam></d></b>
  <a>more</a>
  <x>no no no</x>
</root>"

doc.xpath('root//*[name()!="a"][name()!="b"]').remove
puts doc
#=> <?xml version="1.0"?>
#=> <root>
#=>   <a>foo</a>
#=>   <b>jim</b>
#=>   <a>more</a>
#=>   
#=> </root>
0 голосов
/ 27 апреля 2011

Если это просто вопрос порядка, и ни один из тегов, которые нужно выделить, не вложен, использование XPath вместо селекторов CSS в Nokogiri должно вернуть теги в том же порядке, в котором они находятся в документе:

doc.xpath("//a | //h3").each { |o| puts o }

Я не уверен, относится ли это поведение к каким-либо спецификациям для Нокогири, так что вы можете быть осторожны, но по моему опыту это правда.

Конечно, если теги, к которым вы стремитесь, когда-либо вкладываются, вам, возможно, потребуется определить, что означает «удалить все теги, кроме определенных» (например, что происходит с удаленными тегами и их содержимым, которые существуют внутри не удаленных тегов и их содержимое и т. д.).

Если ваше требование достаточно сложное, так что запросы XPath его не обрезают, вам может понадобиться "пройтись по DOM", используя что-то вроде doc.root.children, и рекурсивно исследовать дочерние элементы каждого узла.

...