问题
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