在XML Python中查找并替换CDATA属性值

2024-04-29 12:48:34 发布

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

我试图演示查找/替换XML属性的功能,类似于在相关问题(Find and Replace XML Attributes by Indexing - Python)中提出的功能,但用于包含在CDATA字符串中的内容。具体来说,我想知道是否有可能通过索引找到CDATA属性值并将其替换为新值。我试图替换第一组“td”子元素中的第一个和第二个属性值,以及第二组“td”子元素中的第二个和第三个属性值。下面是XML,以及我正在使用的脚本和要添加到所需输出XML的新值:

XML(“foo\u bar\u CDATA.XML”):

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Overlay>
    <description>
    <![CDATA[
    <html>
    <head>
        <body>
            <div id="view">
                <div class="item">
                    <tr id="source">
                        <td class="raster">Source</td>
                        <td class="number">1800</td>
                        <td class="number">2100</td>
                    </tr>
                    <tr id="preview">
                        <td class="raster">Preview</td>
                        <td class="number">1100</td>
                        <td class="number">1500</td>
                    </tr>
                </div>
            </div>
        </body>
    </head>
    </html>
    ]]>
    </description>   
</Overlay></kml>

剧本:

import lxml.etree as ET
xml = ET.parse("C:\\Users\\mdl518\\Desktop\\bar_foo_CDATA.xml")
tree=xml.getroot().getchildren()[0][1]

val_1 = 1900
val_2 = 2000
val_3 = 3000
val_4 = 4000

# Find and replace the "td" subelement attribute values with the new values (val_"x") 
for elem in tree.getiterator():
    if elem.text:
        elem.text=elem.text.replace('Source',val_1)
    if elem.text:
        elem.text=elem.text.replace('1800',val_2)
    if elem.text:
        elem.text=elem.text.replace('1100',val_3)
    if elem.text:
        elem.text=elem.text.replace('1500',val_4)
    print(elem.text)

    output = ET.tostring(tree, 
                 encoding="UTF-8",
                 method="xml", 
                 xml_declaration=True, 
                 pretty_print=True)

    print(output.decode("utf-8"))

所需的输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Overlay>
    <description>
    <![CDATA[
    <html>
    <head>
        <body>
            <div id="view">
                <div class="item">
                    <tr id="source">
                        <td class="raster">1900</td>
                        <td class="number">2000</td>
                        <td class="number">2100</td>
                    </tr>
                    <tr id="preview">
                        <td class="raster">Preview</td>
                        <td class="number">3000</td>
                        <td class="number">4000</td>
                    </tr>
                </div>
            </div>
        </body>
    </head>
    </html>
    ]]>
    </description>   
</Overlay></kml>

我的主要问题是正确地索引/读取属性,而不是硬编码所需的值,因为正确地索引它们以查找/替换新值是理想的。对于没有CDATA字符串的XML,上述方法似乎是可行的,但我无法确定如何正确解析CDATA内容,包括将XML正确写入文件。此外,开头和结尾标记(<;,>;)被错误地写为&;燃气轮机及;它位于XML中。非常感谢您的帮助


Tags: textdividnumber属性valxmlkml
1条回答
网友
1楼 · 发布于 2024-04-29 12:48:34

由于CDATA是一个HTML字符串,我会将其从XML中提取出来,对其进行更改,然后将其重新插入XML中:

#first edit
cd = etree.fromstring(doc.xpath('//*[local-name()="description"]')[0].text) #out of the XML

vals = ["1900","2000","3000","4000"]
rems = ["Source","1800","1100","1500"]
targets = cd.xpath('//tr//td')
for target in targets:
    if target.text in rems:
        target.text=vals[rems.index(target.text)]
#second edit
doc.xpath('//*[local-name()="description"]')[0].text = etree.CDATA(etree.tostring(cd)) #... and back into the XML as CDATA
    
print(ET.tostring(tree).decode())

输出应该是您期望的输出

相关问题 更多 >