简体   繁体   English

删除和替换XML文件中的特定节点

[英]Removing and replacing specific nodes in an XML file

I have been working on a project that analyses a musical score and removes specific notes from it. 我一直致力于一个分析乐谱并从中删除特定音符的项目。 So now that I have the information required from my code I now need to edit the original XML score with my new information. 现在我已经从我的代码中获得了所需的信息,现在我需要使用我的新信息编辑原始XML分数。 I am doing this in Python and have already used Minidom so I would obviously like to stick to that (I know this was perhaps a silly choice as a lot of the posts on here recommend different methods of XML parsing due to the not so friendly interface present in Minidom). 我在Python中这样做并且已经使用了Minidom所以我显然希望坚持这一点(我知道这可能是一个愚蠢的选择,因为这里的很多帖子推荐不同的XML解析方法,因为不太友好的界面目前在Minidom)。

So say in my original XML file I have a musical piece made up of just 10 notes. 所以在我原来的XML文件中说我有一个由10个音符组成的音乐作品。 The XML format for a note is shown below: 注释的XML格式如下所示:

<note>
  <pitch>
    <step>E</step>
    <alter>-1</alter>
    <octave>5</octave>
  </pitch>
  <duration>72</duration>
</note>

So this would be repeated 10 times for each note value. 因此,对于每个音符值,这将重复10次。 Now that I have done my analysis I want to remove 5 of these notes. 现在我已经完成了我的分析,我想删除其中的5个注释。 By remove I mean replace with a rest (as it is a musical score after all and it has a shape to conform to). 删除我的意思是替换为休息(因为它毕竟是一个乐谱,它有一个符合的形状)。 So the format for a rest in an XML file is shown below: 因此,XML文件中休息的格式如下所示:

<note>
    <rest/>
    <duration>72</duration>
</note>

So all that I have to do is remove the pitch tag and replace it with a rest tag. 所以我要做的就是删除音高标签并用其他标签替换它。 However I am unsure on how to go about this, haven't really found anything from my searching that seems similar. 但是我不确定如何解决这个问题,从我的搜索中找不到任何看似相似的内容。

I am not too bothered about finding where the notes to be removed are, as I have written a quick test harness to show how I would go about that below in Python (xml_format is essentially just a list of dictionaries containing my new information). 我并不太关心要删除要删除的注释的位置,因为我已经编写了一个快速测试工具来展示我将如何在Python中进行下面的操作(xml_format本质上只是包含我的新信息的字典列表)。 It contains the same number of notes as the original XML file, with the only difference being that some of them are now marked for being removed. 它包含与原始XML文件相同数量的注释,唯一的区别是它们中的一些现在被标记为被删除。 So the original file could have notes like : G, Bb, D, C, G, F, G, D, Bb and the xml_format would have G, Bb, D, REMOVE, G, REMOVE, G, D, Bb etc. 所以原始文件可能有如下注释:G,Bb,D,C,G,F,G,D,Bb和xml_format将有G,Bb,D,REMOVE,G,REMOVE,G,D,Bb等。

I have just returned a at the moment to make sure that the correct number of notes are being removed. 我刚刚回来了,以确保删除正确数量的笔记。

def remove_notes(xml_format, filename):

doc = minidom.parse(filename)                 
count = 0
a = 0
note = doc.getElementsByTagName("note")  

for item in note:
    if xml_format[count]['step'] == 'Remove':
        a = a + 1
        # THEN REMOVE THE ENTIRE PITCH TAG, REPLACE WITH REST
    count = count + 1
    # ELSE DON'T DO ANYTHING

return a 

So basically I am just looking for some assistance in the kind of syntax or code that could be used to remove a specific node at a specific point and then be replaced with a new node, before being written to a new file. 所以基本上我只是在寻找一些语法或代码的帮助,这些语法或代码可以用来删除特定点的特定节点,然后在写入新文件之前用新节点替换。 Thank you very much for any help and I do hope that this is something which is possible (the logic doesn't seem complicated, but who knows what is possible)! 非常感谢你的帮助,我希望这是可能的(逻辑似乎并不复杂,但谁知道什么是可能的)!

What you need to do for every <note> node is: 您需要为每个<note>节点执行的操作是:

  1. Create a new <rest/> node 创建一个新的<rest/>节点
  2. Locate the <pitch> node 找到<pitch>节点
  3. Replace the <pitch> node with the new <rest/> node 用新的<rest/>节点替换<pitch> <rest/>节点

Here is the code: 这是代码:

def remove_notes(xml_format, filename):
    doc = minidom.parse(filename)                 
    count = 0
    a = 0
    note_nodes = doc.getElementsByTagName("note")  

    for note_node in note_nodes:
        if xml_format[count]['step'] == 'Remove':
            a = a + 1

            # Create a <rest/> node
            rest_node = note_node.ownerDocument.createElement('rest')

            # Locate the <pitch> node
            pitch_node = note_node.getElementsByTagName('pitch')[0]

            # Replace pitch with rest
            note_node.replaceChild(rest_node, pitch_node)

        count = count + 1
        # ELSE DON'T DO ANYTHING

    # Finished with the loop, doc now contains the replaced nodes, we need
    # to write it to a file    

    return a 

Please note that you will need to write the changes to a new file or your changes will be lost. 请注意,您需要将更改写入新文件,否则您的更改将会丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM