2017-06-14 19 views
2

XMLファイルを読み込んで文字列を特定の値に置き換える必要があります。 XMLにはCDATA要素が含まれており、それを保存する必要があります。 私はパーサーを使用し、strip_dataをfalseに設定しようとしました。これは機能しておらず、それを達成する方法を理解する助けが必要です。以下はstrip_cdata = Falseを使用してもCDATAがlxmlで削除される

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") 

サンプルXMLです:CDATA、

<?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 

>

をあなたが見ることができるように:コードの出力は以下のようになり


 <?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> 

セクションが取り除かれます。 誰かが私をここで助けることができればそれは素晴らしいことでしょう。あなたは、通常のテキストノードとCDATAを置き換え

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

をやっているので、

答えて

2

です。 .textプロパティは、テキストコンテンツはCDATAセクションでラップされていること兆候を与えるものではありませんか

documentation状態

注意。データがCDATAブロックでラップされていることを確認したい場合は、CDATA()テキストラッパーを使用できます。どのようElementTree

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

:あなたはCDATAセクションを維持したい場合は

したがって、あなただけのCDATAセクションを使用するようにあなたがそれを変更している場合elem.textに割り当て、そしてlxmlのを指示する必要がありますライブラリが動作します(テキストとCDATAの内容全体が連結され、.textプロパティのstrとして公開されています)、CDATAが元々使用されていたかどうかは分かりません。 (Figuring out where CDATA is in lxml element?およびthe source codeを参照)

+0

ありがとう、あなたの説明は意味をなさない。解決方法を試してみましょう。 – Anky

+0

@Keith、CDATAが空のときにCDATAが使用されているかどうかわかりましたか? '' lxmlは空の文字列を返しますが、空のノードは通常は「None」を返します。 –

+0

@MarcelWilson私のテストではあなたの勘違いを確認しています:) 'remove_blank_text = True'でも、CDATAはそのままです。 –

関連する問題