Как переместиться по DOM использование Nokogiri

Вы передаете, затем эхо после завершения цикла, таким образом, печатая только последнее значение. То, что вы хотите:

" .$row1 . "";
}
?>

FWIW, я предполагаю, что это происходит, потому что вы не понимаете, что происходит, когда вы опускаете фигурную скобку после объявления foreach. Оповещение о спойлере: цикл foreach завершился до ?>. Это может помочь прояснить ситуацию: PHP - If / else, for, foreach, while - без фигурных скобок?

7
задан Community 23 May 2017 в 12:31
поделиться

5 ответов

Подход, который я проявил бы (если я понимаю Вашу проблему) должен использовать XPath или CSS для поиска "start_here" элемента и родительского элемента, под которым Вы хотите искать. Затем рекурсивно обойдите дерево, запускающееся в родителе, остановившись при ударе "start_here" элемента, и содержащий на последний элемент, который соответствует стилю по пути.

Что-то как:

parent = value.search("//body").first
div = value.search("//div[@id = 'X2']").first

find = FindPriorTo.new(div)

assert_equal('Foo', find.find_from(parent, 'h1').text)
assert_equal('Bar', find.find_from(parent, 'h2').text) 

Где FindPriorTo простой класс должен обработать рекурсию:

class FindPriorTo
  def initialize(stop_element)
    @stop_element = stop_element
  end

  def find_from(parent, style)
    @should_stop = nil
    @last_style  = nil

    recursive_search(parent, style)
  end

  def recursive_search(parent, style)
    parent.children.each do |ch|
      recursive_search(ch, style)
      return @last_style if @should_stop

      @should_stop = (ch == @stop_element)
      @last_style = ch if ch.name == style
    end

    @last_style    
  end

end

Если этот подход не достаточно масштабируем, то Вы смогли оптимизировать вещи путем перезаписи recursive_search чтобы не использовать рекурсию и также передать в обоих из стилей, Вы ищете и отслеживаете найденные последние, таким образом, Вы не должны пересекать дерево дополнительное время.

Я также сказал бы, что обезьяна попытки, исправляющая Узел для зацеплений, когда документ становится проанализированным, но это похоже на все это, записана в C. Возможно, Вы могли бы быть лучше обслужены с помощью чего-то другого, чем Nokogiri, который имеет собственный Ruby синтаксический анализатор SAX (возможно, REXML), или если скорость является реальным беспокойством, сделайте поисковую часть в использовании C/C++ Xerces или подобный. Я не знаю, как хорошо они будут иметь дело с парсингом HTML все же.

10
ответ дан 6 December 2019 в 19:42
поделиться

Возможно, это сделает это. Я не уверен в производительности и если могли бы быть некоторые случаи, о которых я не думал.

def find(root, start, tag)
    ps, res = start, nil
    until res or (ps == root)
        ps  = ps.previous || ps.parent
        res = ps.css(tag).last
        res ||= ps.name == tag ? ps : nil
    end
    res || "Not found!"
end

parent_element_h1 =  find(parent, start_here, 'h1')
2
ответ дан 6 December 2019 в 19:42
поделиться

Это мое собственное решение (спасибо моему коллеге за помощь в этом!), Использующее рекурсивный метод для анализа всех элементов независимо от того, является ли он родным или дочерним по отношению к другому.

0
ответ дан 6 December 2019 в 19:42
поделиться

Можно искать потомков Nokogiri HTML::Element использование селекторов CSS. Можно пересечь предков с .parent метод.

parent_element_h1 = value.css("h1").first.parent
parent_element_h2 = value.css("h2").first.parent
-1
ответ дан 6 December 2019 в 19:42
поделиться

Если Вы не знаете отношений между элементами, можно искать их этот путь (где угодно в документе):


# html code
text = "insert your html here"
# get doc object
doc = Nokogiri::HTML(text)
# get elements with the specified tag
elements = doc.search("//your_tag")

Если, однако, необходимо отправить форму, необходимо использовать, механизируйте:


# create mech object
mech = WWW::Mechanize.new
# load site
mech.get("address")
# select a form, in this case, I select the first form. You can select the one you need 
# from the array
form = mech.page.forms.first
# you fill the fields like this: form.name_of_the_field
form.element_name  = value
form.other_element = other_value
-1
ответ дан 6 December 2019 в 19:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: