Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Support for explicit xpath option

Default xpath for non-root nodes matches all descendants. Sometimes,
you only want to match the immediate child. The ability to specify
xpath will cover this and other cases.
  • Loading branch information...
commit dbaaebc675dae7104d2c3581056d14d87d4cb362 1 parent 444994b
Riley Martinez-Lynch authored February 16, 2012
8  lib/happymapper.rb
@@ -97,9 +97,11 @@ def parse(xml, options = {})
97 97
       namespace = @namespace || (node.namespaces && node.namespaces.default)
98 98
       namespace = "#{DEFAULT_NS}:#{namespace}" if namespace
99 99
 
100  
-      xpath = root ? '/' : './/'
101  
-      xpath += "#{DEFAULT_NS}:" if namespace
102  
-      xpath += tag_name
  100
+      unless xpath = options[:xpath]
  101
+        xpath = root ? '/' : './/'
  102
+        xpath += "#{DEFAULT_NS}:" if namespace
  103
+        xpath += tag_name
  104
+      end
103 105
 
104 106
       nodes = node.find(xpath, Array(namespace))
105 107
       collection = nodes.collect do |n|
29  spec/fixtures/intrade.xml
... ...
@@ -0,0 +1,29 @@
  1
+<tsResponse requestOp="getUserMessages" resultCode="0" timestamp="1329416249820"
  2
+            timetaken="475">
  3
+   <msg msgID="123456">
  4
+      <msgID>123456</msgID>
  5
+      <conID>789012</conID>
  6
+      <symbol>2012.PIGS.FLY</symbol>
  7
+      <readFlag>false</readFlag>
  8
+      <type>T</type>
  9
+      <msg>345678901</msg>
  10
+      <price>13.0</price>
  11
+      <quantity>100</quantity>
  12
+      <side>B</side>
  13
+      <timestamp>1329415852000</timestamp>
  14
+   </msg>
  15
+   <msg msgID="123460">
  16
+      <msgID>123460</msgID>
  17
+      <conID>789013</conID>
  18
+      <symbol>2012.SNOWBALL.INFERNO.MELT</symbol>
  19
+      <readFlag>false</readFlag>
  20
+      <type>T</type>
  21
+      <msg>345678933</msg>
  22
+      <price>13.0</price>
  23
+      <quantity>100</quantity>
  24
+      <side>S</side>
  25
+      <timestamp>1329415873000</timestamp>
  26
+   </msg>
  27
+   <faildesc>Ok</faildesc>
  28
+   <sessionData>10R3M1p5um0010r5174m37c0n53C737uR401p151C1N931175300031U5m0073mp0r1Nc1010UN7u71480R3370010R3m49n44119u4U73N1M40M1n1MV3n14M9U15n057Ru03X3Rc174710Nu114Mc01480r15n151u74119U1P3x34C0mm000C0n539u470u154u731ruR30010r1Nr3PR3h3n03R171Nv01up7473v31173553C111Um0010R33ufU9147nu114P4R147Ur3XC3P73uR51n70CC43C47CuP104747n0nPR0103N75un71ncu1p49U10fF1C140353rUn7m011174N1M103571480Rum</sessionData>
  29
+</tsResponse>
13  spec/happymapper_spec.rb
@@ -350,6 +350,19 @@ class Thing
350 350
     # tree.people.first.id.should == 'KWQS-BBQ'
351 351
   end
352 352
 
  353
+  it "should support :xpath option" do
  354
+    message_box = Intrade::Messages.parse(fixture_file('intrade.xml'))
  355
+    message_box.timestamp.should == Time.at(1329416249)
  356
+    message_box.error_message.should == "Ok"
  357
+
  358
+    # default xpath would default to './/msg', which would include
  359
+    # nested nodes which are also named "msg", so xpath is
  360
+    # explicitly supplied as option :xpath => './msg'
  361
+    message_box.messages.should have(2).messages
  362
+    message_box.messages[0].message_id.should == 123456
  363
+    message_box.messages[1].message_id.should == 123460
  364
+  end
  365
+
353 366
   describe 'nested elements with namespaces' do
354 367
     module Namespaces
355 368
       class Info
37  spec/support/models.rb
@@ -299,4 +299,39 @@ class Note
299 299
 
300 300
     content :body
301 301
   end
302  
-end
  302
+end
  303
+
  304
+module Intrade
  305
+  class EpochMillis
  306
+    def self.parse(millis); Time.at(millis.to_i / 1000); end
  307
+  end
  308
+
  309
+  class Message
  310
+    include HappyMapper
  311
+
  312
+    tag 'msg'
  313
+    attribute :message_id, Integer, :tag => 'msgID'
  314
+    element :contract_id, Integer, :tag => 'conID'
  315
+    element :symbol, String, :tag => 'symbol'
  316
+    element :is_read, Boolean, :tag => 'readFlag'
  317
+    element :type, String, :tag => 'type'
  318
+    element :text, String, :tag => 'msg'
  319
+    element :price, Float, :tag => 'price'
  320
+    element :quantity, Integer, :tag => 'quantity'
  321
+    element :side, String, :tag => 'side'
  322
+    element :timestamp, EpochMillis, :tag => 'timestamp', :parser => :parse
  323
+  end
  324
+
  325
+  class Messages
  326
+    include HappyMapper
  327
+
  328
+    tag 'tsResponse'
  329
+    attribute :operation, String, :tag => 'requestOp'
  330
+    attribute :timestamp, EpochMillis, :tag => 'timestamp', :parser => :parse
  331
+    attribute :result_code, Integer, :tag => 'resultCode'
  332
+    element :error_message, String, :tag => 'faildesc'
  333
+    element :session_key, String, :tag => 'sessionData'
  334
+    has_many :messages, Message, :tag => 'msg', :xpath => './msg'
  335
+  end
  336
+end
  337
+

0 notes on commit dbaaebc

Please sign in to comment.
Something went wrong with that request. Please try again.