extract and assign xml values to variable

hi,    how can we assign an xml element value to some variable in controller? e.g. if we have <order>    <id>1</id>    <name>abc</name>    <location>xyz</location> </order> and if we want value of name i.e. 'abc' to be assigned in a variable declared in a controller, say order_controller, like this- temp = "value of xml element name i.e. abc". how can we do that? thanks in advance :slight_smile:

-Dhaval

have a look at hpricot: http://code.whytheluckystiff.net/hpricot/

hi,    thanks for the link Thorsten. in my application, i'm using builder. actually, i could generate an xml, post it and get a response in xml only. what i want to know is, thr is an element called result having either success or fail value and i want to show a msg depending upon the value. like if it has success the msg may be "action processed" or if its fail then msg may be "action failed" something like that. can you help me in this pls?

P.S.:- the xml request generation and response code is written in model and it sends request in xml and gets response in xml. i need to have the result's value in its controller. i hope i've provided the required details.

-Dhaval

I'm not sure if you really should have that in your model, but here's what I have in my controller to check for a successful FedEx rate available request. Get ready for some ugly code that works:

@resp, @data = h.post(path, xmlrequest, headers) doc = REXML::Document.new(@data) if doc.root.elements["HighestSeverity"] && doc.root.elements["HighestSeverity"].text.upcase == 'SUCCESS'   services = REXML::XPath.match(doc, "//ServiceType")   @services_and_rates = services.collect do |s|     [s.text, s.parent.parent.elements["RatedShipmentDetails"].elements["ShipmentRateDetail"].elements["TotalNetCharge"].elements["Amount"].text.to_f + (0.006 * @cart.total_price.to_f)]   end end

I'm sure that there are better ways to do this, but this worked when I had to figure it out. Essentially, I'm checking for a value of "SUCCESS" in the only "HighestSeverity" container in the response. If it was successful, I go on and look for each value for "ServiceType". I match the text of the service type with the rate by traversing using a series of child and parent functions. I create an array for later use.

Somebody once mentioned (I think) that you might be able to check XML values by looking in the params of the response. I'd look into that if I were you.

-Kyle

hi,    thanks Kyle. that help me. i'd the same case in my response, "success" or "failure", and i could get this now. but now the next prb is, i need to print the values from the response itself on the page(as if we do for any other object using for loop), if the response is success. e.g. if response has success and the values as - <order>    <id>1</id>    <personalDetails>       <firstName>abc</firstName>       <lastName>def</lastName>       <locationName>xyz</locationName>    </personalDetails>    <address>       <bldg>21</bldg>       <street>asd</street>       <city>qwe</city>       <state>zxc</state>    </address> </order>

then i need to print it as    First Name : abc    Last Name : def    Location Name : xyz    Building : 21    street : asd    city : qwe    state : zxc

   i tried to print the response directly, but that printed all values in single line without a space. i also searched on internet, but couldn't find anything with such requirement. is thr a way to get such an output? Thanks in adv :slight_smile:

-Dhaval

Yes, you can do that. Read up a bit on REXML or other XML parsing engines for Rails. My example above finds the "ServiceType" container, goes to its parent, then its parent, then its child named "RatedShipmentDetails", its child named "ShipmentRateDetail", its child named "TotalNetCharge", and finally, its child "Amount". To get the value, I used .text to specify that I want what's inside of the container.

Essentially, you can create a REXML document based on "//order//id" and assign values the same way:

first_name = doc.root.elements["personalDetails].elements["firstName"].text last_name = ...

You get the idea. I'm sure that there are better ways to do this, so please look around. Thorsten mentioned hpricot earlier, so see if it will better suit your needs. Try to see if params["order"]["id"] ["personalDetails"]["firstName"] can get you what you're looking for. All in all, look around. I didn't pay much attention to the "best" way to do things when I wrote a lot of my first code, and now I have a hard-to-maintain app. See what you can find that might work better than what I've given you.

-Kyle

hi,    thanks kyle, u mentioned the details very well. actually i have almost 50 fields in my response xml, so was finding some better and proper way to do it rather than putting each element in seperate variable. but anyways, i'll keep searching the better way and will put it here if i find any. for time being, i'll use this method only.    thanks once again :slight_smile:

-Dhaval

hi,    sorry to start this thread again. but i'm having a prb again printing the xml values in the view. as i'd mentioned earlier that i have almost 50 fields in the response xml. its a single record fetched from the order table. what i'm trying to do is to assign those xml values to the relevant textfields in a partial, but not able to. it prints the value with xml tags .e.g. <firstName>abc</firstName> instead of only abc. but if i print those values outside the textfield, it doesn't take those tags and prints as abc. can anybody help me in this pls? thanks in advance :slight_smile:

-D