题
我正在写一个AppleScript播放列表产生器。过程的一部分是读iTunes曲库的XML文件,以获得用户的库中的所有类型的列表。这是Python实现,其工作方式我想:
#!/usr/bin/env python
# script to get all of the genres from itunes
import re,sys,sets
## Boosted from the internet to handle HTML entities in Genre names
def unescape(text):
def fixup(m):
text = m.group(0)
if text[:2] == "&#":
# character reference
try:
if text[:3] == "&#x":
return unichr(int(text[3:-1], 16))
else:
return unichr(int(text[2:-1]))
except ValueError:
pass
else:
# named entity
try:
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
except KeyError:
pass
return text # leave as is
return re.sub("&#?\w+;", fixup, text)
# probably faster to use a regex than to try to walk
# the entire xml document and aggregate the genres
try:
xml_path = "/Users/%s/Music/iTunes/iTunes Music Library.xml" % sys.argv[1]
except:
print '\tUsage: python '+sys.argv[0]+' <your OSX username>'
raise SystemExit
pattern = "<key>Genre</key><string>([^<]+)</string>"
try:
xml = file(xml_path,'r').read()
except:
print '\tUnable to load your iTunes Library XML file'
raise SystemExit
matches = re.findall(pattern,xml)
uniques = map(unescape,list(sets.Set(matches)))
## need to write these out somewhere so the applescript can read them
sys.stdout.write('|'.join(uniques))
raise SystemExit
问题是,我想要的AppleScript是自包含的,不需要该附加文件出现(我打算使此提供给其他人)。而且,据我所知,AppleScript的不提供任何类型的正则表达式的能力开箱。我可以遍历库中的每首曲目让所有的流派,但是这是一个过于漫长的过程建立播放列表的时候,我已经做一次。所以,我正在寻找替代品。
由于AppleScript的可以让我运行一个shell脚本,并捕获结果,我想,我可以使用某种类型的shell命令完成同样的行为,无论是用grep,Perl或其他什么东西。我的* nix命令行技能是非常生疏,我找了一些指导。
因此,总之,我想找到一种方法来翻译上面的Python代码到的东西,我可以从外壳直接调用,并得到了类似的结果。谢谢!
解决方案
为什么要使用正则表达式解析XML?为什么不使用正确的XML库? Python有像ElementTree的一些伟大的事业,使走DOM轻松了很多,而且它产生很好的,友好的对象,而不是类型化的字符串。
下面是使用AppleScript解析XML的一些方法:
AppleScript的XML分析器(可用自虎显然)
记住,就像AppleScript的可以钩到iTunes,它可以挂接到其它安装实用程序等这些。
最后,为什么不直接用Python语言编写了整个事情,因为它有办法更好的开发工具进行调试和运行速度快了很多。如果你正在运行Leopard,你的Python 2.5.1预装。
其他提示
如果您已在AppleScript的工作,为什么不问的iTunes直接?
tell application "iTunes" to get genre of every track of library playlist 1
不隶属于 StackOverflow