用于检索具有给定标记属性的节点的bash/python脚本

2024-04-23 10:03:37 发布

您现在位置:Python中文网/ 问答频道 /正文

那个文档.xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<document version="4">
    <tool version="21.4"/>
    <notes>
        <note id="minor" message="dont forget">
            <place file="path/to/fileA" line="81"/>
        </note>
        <note id="major" message="quite well">
            <place file="path/to/fileB" line="11"/>
            <place file="path/to/fileC" line="67"/>
        </note>
        <!-- ... -->
        <note id="medium" message="keep going">
            <place file="path/to/fileF" line="789"/>
            <place file="path/to/fileA" line="91"/>
            <!-- ... -->
            <place file="path/to/fileK" line="6"/>
        </note>
    </notes>
</document>

我需要一个脚本,可以“grep”以上基于'文件'属性的<note>标签。你知道吗

例如:

提示$xmlgrep“path/to/fileA”文档.xml你知道吗

会导致:

<?xml version="1.0" encoding="UTF-8"?>
<document version="4">
    <tool version="21.4"/>
    <notes>
        <note id="minor" message="dont forget">
            <place file="path/to/fileA" line="81"/>
        </note>
        <note id="medium" message="keep going">
            <place file="path/to/fileF" line="789"/>
            <place file="path/to/fileA" line="91"/>
            <place file="path/to/fileK" line="6"/>
        </note>
    </notes>
</document>

你能给我推荐一些吗?优雅的?如何实现?你知道吗

致以最诚挚的问候


Tags: 文件topath文档idmessageversionline
2条回答

下面的代码运行良好,但不是格式良好的xml

import xml.etree.ElementTree as ET
import sys
path = sys.argv[1]
xml_file = sys.argv[2]
tree = ET.parse(xml_file)
root = tree.getroot()
notes = root.find('notes')
for note in notes:
    found_any_path = False
    for place in note[:]:
        if place.attrib['file'] == path:
            found_any_path = True
    else:
        if not found_any_path:
            notes.remove(note)

print ET.tostring(root, encoding="UTF-8", method="xml")

对此,您可能应该使用xml解析器而不是正则表达式。例如:

from lxml import etree
doc = etree.parse('./doc.xml')
notes = doc.findall('notes')
for notes_el in notes:
    note = notes_el.findall('note')
    for note_el in note:
        found = False
        for p in note_el.iter('place'):
            if p.attrib['file'] == 'path/to/fileA':
                found = True
        if not found:
            notes_el.remove(note_el)
print etree.tostring(doc)

相关问题 更多 >