第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用元素樹刪除xml節(jié)點的所有內(nèi)容和子元素

使用元素樹刪除xml節(jié)點的所有內(nèi)容和子元素

猛跑小豬 2022-12-20 14:03:48
我有一個 XML 文件,想刪除具有給定屬性=值的節(jié)點內(nèi)的所有內(nèi)容,但一直無法使元素樹.remove()方法起作用。我得到一個list.remove(x): x not in list錯誤。如果我有一個包含多個段落和列表元素的 div,v1-9,deleted我希望能夠刪除整個 div 及其所有內(nèi)容的屬性。import xml.etree.ElementTree as ET#get target filetree = ET.parse('tested.htm')#pull into element treeroot = tree.getroot()#confirm outputprint(root)#define xlmns tagsMadCap = {'MadCap': 'http://www.madcapsoftware.com/Schemas/MadCap.xsd'}i=1j=6# specify state            state = "state.deleted-in-vers"            # specify version            vers = "version-number.v{}-{}".format(i,j)            # combine to get conditional string might need to double up b/c of order mattering here???            search = ".//*[@MadCap:conditions='{},{}']".format(vers,state)            #get matching elements            for elem in root.findall(search, MadCap):                print('---PARENT---')                print(elem)                print('attributes:', elem.attrib)                print('text:', elem.text)                elem.text = " "                elem.attrib = {}                for child in elem.iter():                    print('-child element-')                    print(child)                    elem.remove(child)            print('==========')為簡單起見,我在上面省略了 i 和 j 上的循環(huán)。這是目標 xml 的片段,因此您可以看到如何使用這些屬性。
查看完整描述

1 回答

?
慕神8447489

TA貢獻1780條經(jīng)驗 獲得超1個贊

我發(fā)現(xiàn)使用lxml更容易完成任務,因為更容易刪除元素。


試試下面的代碼:


from lxml import etree as et


def remove_element(el):

    parent = el.getparent()

    if el.tail.strip():

        prev = el.getprevious()

        if prev is not None:

            prev.tail = (prev.tail or '') + el.tail

        else:

            parent.text = (parent.text or '') + el.tail

    parent.remove(el)


# Read source XML

parser = et.XMLParser(remove_blank_text=True)

tree = et.parse('Input.xml', parser)

root = tree.getroot()

# Replace the below namespace with your proper one

ns = {'mc': 'http://dummy.com'}

# Processing

for it in root.findall('.//*[@mc:conditions]', ns):

    attr = it.attrib

    attrTxt = ', '.join([ f'{key}: {value}'

        for key, value in attr.items() ])

    print(f'Elem.: {et.QName(it).localname:6}: {attrTxt}')

    delFlag = False

    cond = attr.get('{http://dummy.com}conditions')

    if cond:

        dct = { k: v for k, v in (x.split('.')

            for x in cond.split(',')) }

        vn = dct.get('version-number')

        st = dct.get('state')

        if vn == 'v1-6' and st.startswith('deleted'):

            delFlag = True

        print(f"    {vn}, {st:15}  {'Delete' if delFlag else 'Keep'}")

        if delFlag:

            remove_element(it)

# Print the result

print(et.tostring(tree, method='xml',

    encoding='unicode', pretty_print=True))

當然,在目標版本中添加將此樹保存到輸出文件。


為了使用單個根元素正確格式化 XML,我將您的內(nèi)容封裝在:


<main xmlns:MadCap="http://dummy.com">

   ...

</main>

編輯

在我以前的解決方案中,我曾經(jīng)it.getparent().remove(it)刪除有問題的元素。但后來我發(fā)現(xiàn)了一個缺陷,如果源 XML 包含“混合內(nèi)容”,即被刪除元素之后的“尾部”文本也被刪除(但它不應該),這個缺陷就會變得可見。

為了防止它,我添加了remove_element函數(shù)以刪除元素本身并調(diào)用它而不是以前的it.getparent().remove(it)。

評論中問題后的解釋

attrTxt的來源是attr字典的內(nèi)容(當前元素的屬性)。這個片段實際上打印了這本沒有大括號的字典。它僅用于跟蹤,無處可尋。

另一方面,dct扮演著更重要的角色。它的來源是cond,包含(當前元素的)條件屬性的內(nèi)容,例如state.new-in-vers,version-number.v1-6。

這段代碼:

  • 在逗號上拆分內(nèi)容。

  • 將上述每個部分拆分為一個點。

  • 從這些對創(chuàng)建字典。

然后vn收到版本號 ( v1-6 ) 和st - 狀態(tài) ( new-in-vers )。這是嵌入這里的重要情報。由于這兩個片段可能以不同的順序出現(xiàn),因此您無法創(chuàng)建任何匹配所有可能情況的XPath表達式。但是如果你檢查上面的變量,這個元素是否應該被刪除就變得很明顯了。


查看完整回答
反對 回復 2022-12-20
  • 1 回答
  • 0 關注
  • 105 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號