Using Nokogiri to search through XML file based on user input in Rails app

∥☆過路亽.° 提交于 2019-12-24 09:46:00

问题


So I've got an XML file (XML file) with a schema (XML schema).

I'm trying to create a quick Rails app to allow users to search through the XML file based on the 'lastName" element that are children of an sdnEntry element.

I don't have any problems setting up the rails app, or the search-form. I was also able to get the XML file loaded using Nokogiri and can run simple commands like...

xmldoc.css("lastName")

...to return a NodeSet with all the 'lastName' elements in them. Unfortunately, that's not good enough, since that lists not just the 'lastName' elements directly underneath an 'sdnEntry' element. Plus that doesn't even get me started to insert the user's input from the form. I was thinking something like this would work...

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

...but that didn't work. Oddly, I couldn't even get...

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

...to work. I just don't know enough about Nokogiri or XPath or CSS queries for XML documents to figure out how to pass the param from user-input form to create the appropriate query that will return the right info for me.

I tried looking through the Nokogiri Documentation and the W3Schools XPath Tutorial. No joy.

I would really appreciate any pointers, code snippets or suggestions. Thank you.


回答1:


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"]

Instead of requiring the exact text value, you might also be interested in the XPath functions contains() or starts-with().




回答2:


Your issue is with the XPath that Nokogiri is using. You need to specify what the namespace is in attributes. More info at the Nokogiri documentation.

Here is an example for looking up an item, using your params will probably work as well.

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.">]>]


来源:https://stackoverflow.com/questions/8017667/using-nokogiri-to-search-through-xml-file-based-on-user-input-in-rails-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!