سؤال

لدي وثيقة XML التالية:

<node0>
    <node1>
      <node2 a1="x1"> ... </node2>
      <node2 a1="x2"> ... </node2>
      <node2 a1="x1"> ... </node2>
    </node1>
</node0>

اريد التصفية node2 متى a1="x2". يوفر المستخدم قيم XPath والسمة التي تحتاج إلى اختبار وتصفيتها. لقد نظرت إلى بعض الحلول في بيثون مثل BeautifulSoup لكنها معقدة للغاية ولا تحافظ على حالة النص. أريد الاحتفاظ بالوثيقة كما كان من قبل مع بعض الأشياء التي تمت تصفيتها.

هل يمكنك أن تنصح بحل بسيط ومختصر؟ هذا لا ينبغي أن يكون معقدًا جدًا من مظهره. وثيقة XML الفعلية ليست بسيطة على النحو الوارد أعلاه ولكن الفكرة هي نفسها.

هل كانت مفيدة؟

المحلول

هذا يستخدم xml.etree.ElementTree التي هي في المكتبة القياسية:

import xml.etree.ElementTree as xee
data='''\
<node1>
  <node2 a1="x1"> ... </node2>
  <node2 a1="x2"> ... </node2>
  <node2 a1="x1"> ... </node2>
</node1>
'''
doc=xee.fromstring(data)

for tag in doc.findall('node2'):
    if tag.attrib['a1']=='x2':
        doc.remove(tag)
print(xee.tostring(doc))
# <node1>
#   <node2 a1="x1"> ... </node2>
#   <node2 a1="x1"> ... </node2>
# </node1>

هذا يستخدم lxml, ، وهي ليست في المكتبة القياسية ، ولكن لديها بناء جملة أكثر قوة:

import lxml.etree
data='''\
<node1>
  <node2 a1="x1"> ... </node2>
  <node2 a1="x2"> ... </node2>
  <node2 a1="x1"> ... </node2>
</node1>
'''
doc = lxml.etree.XML(data)
e=doc.find('node2/[@a1="x2"]')
doc.remove(e)
print(lxml.etree.tostring(doc))

# <node1>
#   <node2 a1="x1"> ... </node2>
#   <node2 a1="x1"> ... </node2>
# </node1>

يحرر: إذا node2 يتم دفنه بعمق أكبر في XML ، ثم يمكنك التكرار من خلال جميع العلامات ، تحقق من كل علامة الوالدين لمعرفة ما إذا كان node2 العنصر هو أحد أطفاله ، وإزالته إذا كان الأمر كذلك:

باستخدام فقط xml.etree.elementtree:

doc=xee.fromstring(data)
for parent in doc.getiterator():
    for child in parent.findall('node2'):
        if child.attrib['a1']=='x2':
            parent.remove(child)

باستخدام LXML:

doc = lxml.etree.XML(data)
for parent in doc.iter('*'):
    child=parent.find('node2/[@a1="x2"]')
    if child is not None:
        parent.remove(child)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top