簡體   English   中英

即使在使用strip_cdata = False之后CDATA也被剝離了lxml

[英]CDATA getting stripped in lxml even after using strip_cdata=False

我有一個要求,我需要讀取XML文件並替換具有特定值的字符串。 XML包含CDATA元素,我需要保留它。 我嘗試過使用解析器並將strip_data設置為false。 這不起作用,需要幫助找出實現它的方法。

import lxml.etree as ET

parser1 = ET.XMLParser(strip_cdata=False)

with open('testxml.xml', encoding="utf8") as f:
tree = ET.parse(f, parser=parser1)

root = tree.getroot()
for elem in root.getiterator():
    try:
        elem.text = elem.text.replace('Bundled Manager 2.2(8b)', '123456')
    except AttributeError:
        pass

tree.write('output_new8.xml', xml_declaration=True, method='xml',  encoding="utf8")

以下是Sample xml:


     <?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Copyright   (c) 2015 Moto Company, LLC. All rights reserved. Moto Confidential/Proprietary Information -->
<Benchmark>
       <status date="2013-03-11">draft</status>
    <title>Logitech TMM block(TM) System 300 Release Certification Matrix</title>
    <description>Random discription</description>
    <version time="2013-03-05T15:20:20.995-04:00" update="">3.0.0-2017.03.00</version>
        <model system="urn:xccdf:scoring:default"/>
    <Profile id="xccdf_com.Moto_profile_release_4.0.21">
        <status date="2016-03-30">draft</status>
        <title>RCM 4.0.21</title>
        <description><![CDATA[<p>Moto Vblock System 300 Release 4.0.21</p>
<ul><li> TMM VNX OE for File was updated to 7.1.79.8.</li>
</ul>]]>
</description>
        <set-value idref="xccdf_com.Moto_value_vision_content_version">3.0.0-2015.07.00</set-value>
        <set-value idref="xccdf_com.Moto_value_vision_version">3.0.0</set-value>
        <set-value idref="xccdf_com.Moto_value_vplex_version">5.3.0.03.00.04</set-value>
        <set-value idref="xccdf_com.Moto_value_powerpath_version">Bundled Manager 2.2(8b)</set-value>       
        <select idref="xccdf_com.Moto_rule_vnx_version" selected="true"/>
        <select idref="xccdf_com.Moto_rule_vplex_version" selected="true"/>
    </Profile>
</Benchmark>

代碼的輸出如下所示:

<?xml version='1.0' encoding='UTF8'?>
<!-- Copyright (c) 2015 Moto Company, LLC. All rights reserved. Moto Confidential/Proprietary Information --><Benchmark>
    <status date="2013-03-11">draft</status>
    <title>Logitech TMM block(TM) System 300 Release Certification Matrix</title>
    <description>Random discription</description>
    <version time="2013-03-05T15:20:20.995-04:00" update="">3.0.0-2017.03.00</version>
        <model system="urn:xccdf:scoring:default"/>
    <Profile id="xccdf_com.Moto_profile_release_4.0.21">
        <status date="2016-03-30">draft</status>
        <title>RCM 4.0.21</title>
        <description>&lt;p&gt;Moto Vblock System 300 Release 4.0.21&lt;/p&gt;
&lt;ul&gt;&lt;li&gt; TMM VNX OE for File was updated to 7.1.79.8.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <set-value idref="xccdf_com.Moto_value_vision_content_version">3.0.0-2015.07.00</set-value>
        <set-value idref="xccdf_com.Moto_value_vision_version">3.0.0</set-value>
        <set-value idref="xccdf_com.Moto_value_vplex_version">5.3.0.03.00.04</set-value>
        <set-value idref="xccdf_com.Moto_value_powerpath_version">123456</set-value>        
        <select idref="xccdf_com.Moto_rule_vnx_version" selected="true"/>
        <select idref="xccdf_com.Moto_rule_vplex_version" selected="true"/>
    </Profile>
</Benchmark

>

如您所見,CDATA部分被剝離。 如果有人能在這里幫助我會很棒。

這是因為你在做

elem.text = elem.text.replace('Bundled Manager 2.2(8b)', '123456')

用普通文本節點替換CDATA。

文件說明

請注意.text屬性如何不表示文本內容由CDATA部分包裝。 如果要確保數據由CDATA塊包裝,可以使用CDATA()文本包裝器。

因此,如果要保留CDATA部分,則只應修改elem.text ,並指示lxml使用CDATA部分:

if 'Bundled Manager 2.2(8b)' in elem.text:
    elem.text = ET.CDATA(elem.text.replace('Bundled Manager 2.2(8b)', '123456'))

由於ElementTree庫的工作方式(整個文本和cdata內容在.text屬性中連接並作為str ),因此無法確定CDATA最初是否使用過。 (請參閱確定CDATA在lxml元素中的位置?源代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM