草庐IT

xml - 更实用的 xml 解析方法

coder 2024-06-26 原文

我正在将一些 xml 映射到一个案例类并且它工作正常,但我有一种感觉,我的命令性眼罩让我看不到更好的功能解决方案。谁能提出比这更好的方法:

def buildAddress(geocodeResponse: NodeSeq) : Address = {
  val addressNodes = geocodeResponse \\ "address_component"
  var street = " "
  var town = ""
  var suburb = ""
  var province = ""
  var country = ""
  var postalCode = ""

  addressNodes.foreach {node =>      
    val typeString = (node \ "type").head.text
    if ("street_number" ==  typeString) {
      street = (node \ "long_name").text + street
    }
    else if ("route" == typeString) {
      street = street + (node \ "long_name").text
    }
    else if ("locality" == typeString) {
      town = (node \ "long_name").text
    }
    else if ("sublocality" == typeString) {
      suburb = (node \ "long_name").text
    }
    else if ("administrative_area_level_1" == typeString) {
      province = (node \ "long_name").text
    }
    else if ("country" == typeString) {
      country =  (node \ "long_name").text
    }
    else if ("postal_code" == typeString) {
      town = (node \ "long_name").text
    }
  }
  Address(street,suburb,town,province,country,postalCode)
}

本例中的 xml 是使用 Dispatch 从 Google 地理编码 API 中检索的。

   import dispatch._ 
   def lookupAddress(lat: Double, long: Double): Address = {
     val position = lat.toString + "," + long.toString
     val req = url("http://maps.googleapis.com/maps/api/geocode/xml") <<? Map("latlng" -> position, "sensor" -> "true")
     Http(req </> {
     nodes => buildAddress(nodes)
     })
   }

xml 结果如下所示:

    <GeocodeResponse>
      <status>OK</status>
      <result>
        <type>street_address</type>
        <formatted_address>3 Louw St, Stellenbosch 7600, South Africa</formatted_address>
        <address_component>
          <long_name>3</long_name>
          <short_name>3</short_name>
          <type>street_number</type>
        </address_component>
        <address_component>
          <long_name>Louw St</long_name>
          <short_name>Louw St</short_name>
          <type>route</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch Central</long_name>
          <short_name>Stellenbosch Central</short_name>
          <type>sublocality</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>locality</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>administrative_area_level_3</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>7600</long_name>
          <short_name>7600</short_name>
          <type>postal_code</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.9403990</lat>
            <lng>18.8610090</lng>
          </location>
          <location_type>ROOFTOP</location_type>
          <viewport>
            <southwest>
              <lat>-33.9435466</lat>
              <lng>18.8578614</lng>
            </southwest>
            <northeast>
              <lat>-33.9372514</lat>
              <lng>18.8641566</lng>
            </northeast>
          </viewport>
        </geometry>
      </result>
      <result>
        <type>sublocality</type>
        <type>political</type>
        <formatted_address>Stellenbosch Central, Stellenbosch, South Africa</formatted_address>
        <address_component>
          <long_name>Stellenbosch Central</long_name>
          <short_name>Stellenbosch Central</short_name>
          <type>sublocality</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>locality</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>administrative_area_level_3</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.9354048</lat>
            <lng>18.8640607</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-33.9437180</lat>
              <lng>18.8449199</lng>
            </southwest>
            <northeast>
              <lat>-33.9230960</lat>
              <lng>18.8778929</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-33.9437180</lat>
              <lng>18.8449199</lng>
            </southwest>
            <northeast>
              <lat>-33.9230960</lat>
              <lng>18.8778929</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>postal_code</type>
        <formatted_address>7599, South Africa</formatted_address>
        <address_component>
          <long_name>7599</long_name>
          <short_name>7599</short_name>
          <type>postal_code</type>
        </address_component>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.9300286</lat>
            <lng>18.8640607</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-33.9693080</lat>
              <lng>18.8019200</lng>
            </southwest>
            <northeast>
              <lat>-33.8700550</lat>
              <lng>18.9232900</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-33.9693080</lat>
              <lng>18.8019200</lng>
            </southwest>
            <northeast>
              <lat>-33.8700550</lat>
              <lng>18.9232900</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>locality</type>
        <type>political</type>
        <formatted_address>Stellenbosch, South Africa</formatted_address>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>locality</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>administrative_area_level_3</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.9366667</lat>
            <lng>18.8613889</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-34.0150869</lat>
              <lng>18.7658819</lng>
            </southwest>
            <northeast>
              <lat>-33.8782960</lat>
              <lng>18.9232900</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-34.0150869</lat>
              <lng>18.7658819</lng>
            </southwest>
            <northeast>
              <lat>-33.8782960</lat>
              <lng>18.9232900</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>postal_code</type>
        <formatted_address>7600, South Africa</formatted_address>
        <address_component>
          <long_name>7600</long_name>
          <short_name>7600</short_name>
          <type>postal_code</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry/>
      </result>
      <result>
        <type>administrative_area_level_3</type>
        <type>political</type>
        <formatted_address>Stellenbosch, South Africa</formatted_address>
        <address_component>
          <long_name>Stellenbosch</long_name>
          <short_name>Stellenbosch</short_name>
          <type>administrative_area_level_3</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.9405478</lat>
            <lng>18.9502232</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-34.0633899</lat>
              <lng>18.7083300</lng>
            </southwest>
            <northeast>
              <lat>-33.7933599</lat>
              <lng>19.2438000</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-34.0633899</lat>
              <lng>18.7083300</lng>
            </southwest>
            <northeast>
              <lat>-33.7933599</lat>
              <lng>19.2438000</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>administrative_area_level_2</type>
        <type>political</type>
        <formatted_address>Brede River DC, South Africa</formatted_address>
        <address_component>
          <long_name>Brede River DC</long_name>
          <short_name>Brede River DC</short_name>
          <type>administrative_area_level_2</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.4220698</lat>
            <lng>19.7591675</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-34.1172599</lat>
              <lng>18.7083299</lng>
            </southwest>
            <northeast>
              <lat>-32.1844899</lat>
              <lng>21.0103399</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-34.1172599</lat>
              <lng>18.7083299</lng>
            </southwest>
            <northeast>
              <lat>-32.1844899</lat>
              <lng>21.0103399</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>administrative_area_level_1</type>
        <type>political</type>
        <formatted_address>Western Cape, South Africa</formatted_address>
        <address_component>
          <long_name>Western Cape</long_name>
          <short_name>WC</short_name>
          <type>administrative_area_level_1</type>
          <type>political</type>
        </address_component>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-33.2277918</lat>
            <lng>21.8568586</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-34.8330538</lat>
              <lng>17.7575638</lng>
            </southwest>
            <northeast>
              <lat>-30.4302599</lat>
              <lng>24.2224100</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-34.8330538</lat>
              <lng>17.7575638</lng>
            </southwest>
            <northeast>
              <lat>-30.4302599</lat>
              <lng>24.2224100</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
      <result>
        <type>country</type>
        <type>political</type>
        <formatted_address>South Africa</formatted_address>
        <address_component>
          <long_name>South Africa</long_name>
          <short_name>ZA</short_name>
          <type>country</type>
          <type>political</type>
        </address_component>
        <geometry>
          <location>
            <lat>-30.5594820</lat>
            <lng>22.9375060</lng>
          </location>
          <location_type>APPROXIMATE</location_type>
          <viewport>
            <southwest>
              <lat>-34.9670000</lat>
              <lng>16.2817000</lng>
            </southwest>
            <northeast>
              <lat>-22.1253869</lat>
              <lng>33.0469000</lng>
            </northeast>
          </viewport>
          <bounds>
            <southwest>
              <lat>-34.9670000</lat>
              <lng>16.2817000</lng>
            </southwest>
            <northeast>
              <lat>-22.1253869</lat>
              <lng>33.0469000</lng>
            </northeast>
          </bounds>
        </geometry>
      </result>
    </GeocodeResponse>

最佳答案

实际上并没有更实用,但是匹配可以稍微清理一下。鉴于您必须查找特定的字符串,并且处理该值的规则取决于字符串,我不确定它可以有多“功能”。

def buildAddress(geocodeResponse: NodeSeq) : Address = {
  val addressNodes = geocodeResponse \\ "address_component"
  var street = " "
  var town = ""
  var suburb = ""
  var province = ""
  var country = ""
  var postalCode = ""

  addressNodes.foreach {node =>      
      lazy val text = (node \ "long_name").text  // lazy so we don't look until we know it should be there
    (node \ "type").head.text match {
        case "street_number" => street =  text + street
        case "route"         => street = street + text
        case "locality"      => town =  text
        case "sublocality"   => suburb = text
        case "administrative_area_level_1" => province = text
        case "country"       => country =  text
        case "postal_code"   => town = text
        case _               => // Hmm. Not sure what is expected here.

    }
  }
  Address(street,suburb,town,province,country,postalCode)
}

编辑:

I'm not sure how much more "functional" it can be.

但话又说回来(注意 - 这又是未经测试的,我需要调试 getComponent,但我希望这个想法很清楚。更正可能会在稍后到达)

def buildAddress(geocodeResponse: NodeSeq) : Address = {
  val addressNodes = geocodeResponse \\ "address_component"

  def getComponent(word:String) = {
        addressNodes.find{_ \ "type".head.text == word)  match {
        case Some(node) => node \ "long_name".text
        case _=> ""
        }
      }

  Address(getComponent("street_number")+getComponent("route"),
               getComponent("suburb"),
               getComponent("town"),
               getComponent("province"),
               getComponent("country"),
               getComponent("postalCode"))

}

关于xml - 更实用的 xml 解析方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6424070/

有关xml - 更实用的 xml 解析方法的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  4. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  5. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  8. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  9. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐