Created
February 14, 2016 16:34
-
-
Save kcurtin/259302e3d66a62b47563 to your computer and use it in GitHub Desktop.
Interfacing with the erlang xmerl library to parse xml data. Using xml files from weather.gov for sample data (http://w1.weather.gov/xml/current_obs/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule WeatherParser do | |
require Record | |
Record.defrecord :xmlElement, Record.extract(:xmlElement, from_lib: "xmerl/include/xmerl.hrl") | |
Record.defrecord :xmlText, Record.extract(:xmlText, from_lib: "xmerl/include/xmerl.hrl") | |
def parse(xml, attrs) do | |
xml | |
|> :binary.bin_to_list | |
|> :xmerl_scan.string | |
|> extract_values(attrs, []) | |
end | |
def extract_values(xml, [], res), do: Enum.reverse(res) | |
def extract_values({xml, _rest}, list, res), do: extract_values(xml, list, res) | |
def extract_values(xml, [h | tail], res) do | |
val = extract_element(xml, h) | |
|> extract_content | |
|> extract_value | |
extract_values(xml, tail, [val | res]) | |
end | |
def extract_element(xml, name), do: :xmerl_xpath.string('/current_observation/#{name}', xml) | |
def extract_content([element]), do: xmlElement(element, :content) | |
def extract_value([content_element]), do: xmlText(content_element, :value) | |
end | |
defmodule WeatherParserTest do | |
use ExUnit.Case | |
test "returns the specified attributes" do | |
data = WeatherParser.parse(sample_xml, [:location, :temp_f, :temp_c]) | |
assert data == ['Unknown Station', '39.2', '4.0'] | |
end | |
def sample_xml do | |
""" | |
<?xml version="1.0" encoding="ISO-8859-1"?> | |
<?xml-stylesheet href="latest_ob.xsl" type="text/xsl"?> | |
<current_observation version="1.0" | |
xmlns:xsd="http://www.w3.org/2001/XMLSchema" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:noNamespaceSchemaLocation="http://www.weather.gov/view/current_observation.xsd"> | |
<credit>NOAA's National Weather Service</credit> | |
<credit_URL>http://weather.gov/</credit_URL> | |
<image> | |
<url>http://weather.gov/images/xml_logo.gif</url> | |
<title>NOAA's National Weather Service</title> | |
<link>http://weather.gov</link> | |
</image> | |
<suggested_pickup>15 minutes after the hour</suggested_pickup> | |
<suggested_pickup_period>60</suggested_pickup_period> | |
<location>Unknown Station</location> | |
<station_id>ALIA2</station_id> | |
<observation_time>Last Updated on Feb 13 2016, 2:30 pm AST</observation_time> | |
<observation_time_rfc822>Sat, 13 Feb 2016 14:30:00 -0400</observation_time_rfc822> | |
<temperature_string>39.2 F (4.0 C)</temperature_string> | |
<temp_f>39.2</temp_f> | |
<temp_c>4.0</temp_c> | |
<water_temp_f>40.3</water_temp_f> | |
<water_temp_c>4.6</water_temp_c> | |
<wind_string>Northeast at 9.2 MPH (7.97 KT)</wind_string> | |
<wind_dir>Northeast</wind_dir> | |
<wind_degrees>60</wind_degrees> | |
<wind_mph>9.2</wind_mph> | |
<wind_gust_mph>0.0</wind_gust_mph> | |
<wind_kt>7.97</wind_kt> | |
<pressure_string>988.5 mb</pressure_string> | |
<pressure_mb>988.5</pressure_mb> | |
<windchill_string>33 F (1 C)</windchill_string> | |
<windchill_f>33</windchill_f> | |
<windchill_c>1</windchill_c> | |
<mean_wave_dir>Northeast</mean_wave_dir> | |
<mean_wave_degrees></mean_wave_degrees> | |
<disclaimer_url>http://weather.gov/disclaimer.html</disclaimer_url> | |
<copyright_url>http://weather.gov/disclaimer.html</copyright_url> | |
<privacy_policy_url>http://weather.gov/notice.html</privacy_policy_url> | |
</current_observation> | |
""" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment