Попытка разобрать, возможно, очень глубоко вложенный XML-файл с Nokogiri - PullRequest
0 голосов
/ 18 сентября 2011

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

У меня есть категория с несколькими вопросами, на каждый вопрос есть несколько ответов, которые могут вызвать один или несколько дополнительных вопросов.

Я сделал упрощенную версию моего XML-файла: https://gist.github.com/1225431

Поскольку я делаю это сам, я также открыт для предложений, если я должен подготовить этот XML-файл по-другому.

questions = doc.css('questions')

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

Я даже использую подходящий инструмент для этой работы? Любая помощь приветствуется.

1 Ответ

1 голос
/ 19 сентября 2011

Nokogiri - отличная библиотека для разбора XML / HTML для Ruby, так что вы определенно используете правильный инструмент для этой работы.Поскольку вы анализируете XML-документ, вы должны использовать XPath вместо CSS-селекторов.К счастью, Nokogiri предлагает вам .

Документация Nokogiri содержит несколько основных полезных руководств по использованию . Этот отвечает на ваш вопрос.

Вот пример кода, специфичный для вашего вопроса.Надеюсь, этого достаточно, чтобы начать работу:

require 'nokogiri'

# Reads the `example.xml` file from the current directory.
file    = File.read("example.xml")

# Uses Nokogiri::XML to parse the file.
doc     = Nokogiri::XML(file)

# Iterate over each <question> element and print 
# the text inside the first <name> element of each.
doc.xpath("//question").each do |q|
    puts q.at("name").text

    # Iterate over each <selection> element within the
    # current question and print its <name> and <conditional> 
    # line "name: conditional"
    q.xpath("./selection").each do |selection|
        puts "#{selection.at("name").text}: #{selection.at("conditional").text}"
    end

    # Same as above, but use variables.
    q.xpath("./selection").each do |selection|
        name                = selection.at("name").text
        conditional = selection.at("conditional").text

        puts "#{name}: #{conditional}"
    end
end
...