我经常使用MusicXML文件,并试图编译一个小节列表,其中有许多小节发生了关键更改。我需要一些帮助,使用python首先确定<key>
标记在XML文件中的位置,然后从上面的<measure number ='*'>
标记中提取数字。以下是我正在使用的一个度量的示例:
<measure number='30' implicit='yes'>
<print new-page='yes'/>
<barline location='left'>
<bar-style>heavy-light</bar-style>
<repeat direction='forward'/>
</barline>
<attributes>
<key>
<fifths>-1</fifths>
<mode>major</mode>
</key>
</attributes>
<direction>
<direction-type>
<dynamics default-y='-82'>
<p/>
</dynamics>
</direction-type>
<staff>1</staff>
</direction>
<direction>
<direction-type>
<words default-y='15' relative-x='4'>
</direction-type>
<staff>1</staff>
</direction>
<note>
<pitch>
<step>F</step>
<octave>5</octave>
</pitch>
<duration>768</duration>
<voice>1</voice>
<type>quarter</type>
<stem>down</stem>
<staff>1</staff>
<notations>
<ornaments>
<trill-mark default-y='20'/>
<wavy-line type='start' number='1'/>
<wavy-line type='stop' number='1'/>
</ornaments>
</notations>
</note>
</measure>
如何提取'30'
位?有没有一种简单快捷的方法可以用music21做到这一点?
在music21中,您可以执行以下操作:
from music21 import *
s = converter.parse(filepath)
# assuming key changes are the same in all parts, just get the first part
p = s.parts[0]
pFlat = p.flat
keySigs = pFlat.getElementsByClass('KeySignature')
for k in keySigs:
print k.measureNumber
对于你感兴趣的简单案例,John K的答案会很好。但是,如果你想做一些更复杂的事情(比如确定密钥更改时的电流表,看看密钥区域是否分析到与签名相同的密钥,等等(,那么music21可能是一个帮助。
(编辑:透露我是该软件包的生产商(。
我不知道Music21。如果您想直接分析XML,可以使用以下单行XPath查询:
//measure[attributes/key]/@number
这找到其中包含<key>
元素的<measure>
元素,然后从这些度量中提取number
属性。有关在Python中执行XPath的信息,请参阅此问题(听起来lxml是最好的方法(。