Использование Nokogiri для поиска в XML-файле на основе пользовательского ввода в приложении Rails - PullRequest
1 голос
/ 05 ноября 2011

Итак, у меня есть XML-файл ( XML-файл ) со схемой ( XML-схема ).

Я пытаюсь создать быстрое приложение на Rails, чтобы пользователи могли осуществлять поиск в XML-файле на основе элемента 'lastName', являющегося дочерним элементом элемента sdnEntry.

У меня нет проблем с настройкой приложения rails или поисковой формы. Я также смог загрузить XML-файл с помощью Nokogiri и выполнять простые команды, такие как ...

xmldoc.css("lastName")

... чтобы вернуть NodeSet со всеми элементами 'lastName'. К сожалению, этого недостаточно, поскольку в нем перечислены не только элементы 'lastName', расположенные непосредственно под элементом 'sdnEntry'. Плюс, это даже не заставляет меня начинать вставку ввода пользователя из формы. Я думал, что-то вроде этого будет работать ...

xmldoc.xpath("/xmlns:sdnList/sdnEntry/lastName[text()='#{param[:name]}']")

... но это не сработало. Как ни странно, я даже не мог получить ...

xmldoc.xpath("/xmlns:sdnList/sdnEntry/lastName")

... на работу. Я просто недостаточно знаю о запросах Nokogiri, XPath или CSS для XML-документов, чтобы понять, как передать параметр из формы ввода пользователя, чтобы создать соответствующий запрос, который вернет мне правильную информацию.

Я попытался просмотреть документацию Nokogiri и учебник W3Schools XPath . Нет радости.

Буду очень признателен за любые указатели, фрагменты кода или предложения. Спасибо.

Ответы [ 2 ]

2 голосов
/ 05 ноября 2011

Ваша проблема связана с XPath, который использует Нокогири. Вам нужно указать, что пространство имен в атрибутах. Больше информации в документации Nokogiri .

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

doc = Nokogiri::XML(File.read("sdn.xml"))
doc.xpath("//sd:lastName[text()='INVERSIONES EL PROGRESO S.A.']", "sd"=>"http://tempuri.org/sdnList.xsd")

>> [#<Nokogiri::XML::Element:0x80b35350 name="lastName" namespace=#<Nokogiri::XML::Namespace:0x80b44c4c href="http://tempuri.org/sdnList.xsd"> children=[#<Nokogiri::XML::Text:0x80b34e3c "INVERSIONES EL PROGRESO S.A.">]>]
1 голос
/ 05 ноября 2011
user_input = "CHOMBO"                # However you are getting it
doc = Nokogiri.XML(myxml,&:noblanks) # However you are getting it
doc.remove_namespaces!               # Simplify your life, if you're just reading

# Find all sdnEntry elements with a lastName element with specific value
sdnEntries = doc.xpath("/sdnList/sdnEntry[lastName[text()='#{user_input}']]")

sdnEntries.each do |sdnEntry|
  p [
    sdnEntry.at_xpath('uid/text()').content, # You can get a text node's contents
    sdnEntry.at_xpath('firstName').text      # …or get an element's text
  ]
end
#=> ["7491", "Ignatius Morgan"]
#=> ["9433", "Marian"]
#=> ["9502", "Ever"]

Вместо точного текстового значения вас могут заинтересовать функции XPath contains() или starts-with().

...