Skip to content

Instantly share code, notes, and snippets.

@kuwa72
Created February 7, 2022 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuwa72/f1d3e618ec33b70b435750c1f53e4643 to your computer and use it in GitHub Desktop.
Save kuwa72/f1d3e618ec33b70b435750c1f53e4643 to your computer and use it in GitHub Desktop.
test of itunes xml parse
require 'rexml/parsers/sax2parser'
require 'rexml/sax2listener'
# define types
module Modes
Unknown = 'Unknown' # unknown key name, ignore parse
TrackID = 'Track ID'
Name = 'Name'
end
class Music
attr :id, :name
def initialize(id)
@id = id
end
end
class Playlist
attr :name, :musics
def initialize(name)
@name = name
@musics = []
end
end
# state control variables
$is_musics = true # a music mode(true) or a playlist mode(false)
$mode = Modes::Unknown
$current_music = nil # instance of current parcing Music
$current_playlist = nil # instance of current parcing Playlist
# code
parser = REXML::Parsers::SAX2Parser.new(ARGF.read)
musics = {} # Hashtable of track_id:Music
playlists = {} # Hashtable of playlist_name:[Playlist]
parser.listen(:characters, ["key"]) do |c|
case c
when Modes::TrackID, Modes::Name
$mode = c
else
$mode = Modes::Unknown
end
$is_music = false if c == 'Playlists'
end
parser.listen(:characters, ["string"]) do |c|
case
when $is_musics && $mode == Modes::Name
# assing music title
$current_music.name = c
when !$is_musics && $mode == Modes::Name
# initialize Playlist
pl = Playlists.new(c)
$current_playlist = pl
playlists[c] = pl
end
end
parser.listen(:characters, ["integer"]) do |c|
case
when $is_musics && $mode == Modes::TrackID
# initialize Music
m = Music.new(c)
$current_music = m
musics[c] = m
when !$is_musics && $mode == Modes::TrackID
# get music and assing to current playlist
m = music[c]
$current_playlist.musics << m
end
end
# mode change to a playlist
parser.listen(:characters, ["key"]){|c| $mode = c == 'Playlists' }
parser.parse
@kuwa72
Copy link
Author

kuwa72 commented Feb 7, 2022

バカ遅いのでXMLパーサつかうのやめた。爆速。

# define types

class Music
  attr_accessor :id, :name
  def initialize(id)
    @id = id
    @name = nil
  end
end

class Playlist
  attr_accessor :name, :musics
  def initialize(name)
    @name = name
    @musics = []
  end
end

# state control variables

is_musics = true # a music mode(true) or a playlist mode(false)
current_music = nil # instance of current parcing Music
current_playlist = nil # instance of current parcing Playlist

musics = {} # Hashtable of track_id:Music
playlists = {} # Hashtable of playlist_name:[Playlist]

while line = ARGF.gets
  # do something
  case
  when is_musics && line =~ %r|<key>Track ID</key><integer>(\d+)|
    id = Regexp.last_match[1]
    m = Music.new(id)
    current_music = m
    musics[id] = m
  when !is_musics && line =~ %r|<key>Track ID</key><integer>(\d+)|
    id = Regexp.last_match[1]
    current_playlist.musics << musics[id]
  when is_musics && line =~ %r|<key>Name</key><string>(.+?)<|
    name = Regexp.last_match[1]
    current_music.name = name
  when !is_musics && line =~ %r|<key>Name</key><string>(.+)<|
    name = Regexp.last_match[1]
    p = Playlist.new(name)
    current_playlist = p
    playlists[name] = p
  when is_musics && line =~ %r|<key>Playlists</key>|
    is_musics = false
  end

end

p playlists['ライブラリ']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment