使用python搜索和替换XMLfile中的元素

2024-05-14 08:13:08 发布

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

我需要搜索元素并替换为XML文件中的另一个值。只能在条件匹配行进行更换。你知道吗

我有以下xml文件。你知道吗

<?xml vn="1.0" encoding="UTF-8"?>
<proj>
    <mV>4.0.0</mV>

    <gId>com.test</gId>
    <aId>console</aId>
    <vn>1.0</vn>

    <bld>
        <plugins>
            <plugin>
                <gId>org.apache.maven.plugins</gId>
                <aId>maven-compiler-plugin</aId>
                <vn>1.1</vn>
                <configuration>
                    <source>1.0</source>
                    <target>1.0</target>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
        </plugins>
    </bld>
    <dps>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-api</aId>
            <vn>1.7.20</vn>
        </dp>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-log</aId>
            <vn>1.7.25</vn>
        </dp>
    </dps>
</proj>

以下是更换代码。你知道吗

aIdValue = "sk-log"
tree = ET.parse('test.xml')
al_rt = tree.getal_rt()
dp = al_rt.findall(".//xmlns:dp")
for d in dp:
    aId = d.find("xmlns:aId")
    vn    = d.find("xmlns:vn")
    if aIdValue == aId.text:
       print aId.text
        print vn.text
        vn.text = vn.text
        tree.write('test.xml')

这里我从print语句得到的值是aId.textsk-logvn.text1.7.25。我只需要在那一行中用somevalue替换1.7.25。上面的代码对我不起作用。我该怎么做?你知道吗

预期输出为

<?xml vn="1.0" encoding="UTF-8"?>
<proj>
    <mV>4.0.0</mV>

    <gId>com.test</gId>
    <aId>console</aId>
    <vn>1.0</vn>

    <bld>
        <plugins>
            <plugin>
                <gId>org.apache.maven.plugins</gId>
                <aId>maven-compiler-plugin</aId>
                <vn>1.1</vn>
                <configuration>
                    <source>1.0</source>
                    <target>1.0</target>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
        </plugins>
    </bld>
    <dps>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-api</aId>
            <vn>1.7.20</vn>
        </dp>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-log</aId>
            <vn>somevalue</vn>
        </dp>
    </dps>
</proj>

Tags: textorgtestpluginsxmlplugindpsk
3条回答

以下是您需要的: 导入xml.etree.ElementTree文件作为ET

tree = ET.parse('test.xml')  
root = tree.getroot()
aIdValue = "sk-log"

for elt in root.iter("dp"):
  print("%s - %s" % (elt.tag, elt.text))
  aId = elt.find("aId")
  vn = elt.find("vn")
  print(aId.text)
  print(vn.text)
  if (aId.text == aIdValue):
    print("vn will be changed.")
    elt.find("vn").text='1.8.0'

tree.write('test.xml', 'unicode')   

使用BeautifulSoupfind_next()

列表_文本.xml地址:

<?xml vn="1.0" encoding="UTF-8"?>
<proj>
    <mV>4.0.0</mV>

    <gId>com.test</gId>
    <aId>console</aId>
    <vn>1.0</vn>

    <bld>
        <plugins>
            <plugin>
                <gId>org.apache.maven.plugins</gId>
                <aId>maven-compiler-plugin</aId>
                <vn>1.1</vn>
                <configuration>
                    <source>1.0</source>
                    <target>1.0</target>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
        </plugins>
    </bld>
    <dps>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-api</aId>
            <vn>1.7.20</vn>
        </dp>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-log</aId>
            <vn>1.7.25</vn>
        </dp>
    </dps>
</proj>

然后:

from bs4 import BeautifulSoup
with open('list_test.xml','r') as f:
    soup = BeautifulSoup(f.read(), "html.parser")
    aid = soup.find_all('aid')
    for s in aid:
        if s.text == 'sk-log':
            vn = s.find_next('vn')
            print("Original Value: {}".format(vn.text))
            vn.string = 'SomeValue'
            print("Replaced value: {}".format(vn.text))

输出:

Original Value: 1.7.25
Replaced value: SomeValue

编辑:

要将其写入同一个xml文件,我们将使用soup.prettify()

from bs4 import BeautifulSoup
with open('list_test.xml','r') as f:
    soup = BeautifulSoup(f.read(), features="lxml")
    aid = soup.find_all('aid')
    for s in aid:
        if s.text == 'sk-log':
            vn = s.find_next('vn')
            print("Original Value: {}".format(vn.text))
            vn.string = 'SomeValue'
            print("Replaced value: {}".format(vn.text))

with open("list_test.xml", "w") as f_write:
    f_write.write(soup.prettify())

输出:

<?xml vn="1.0" encoding="UTF-8"?>
<html>
 <body>
  <proj>
   <mv>
    4.0.0
   </mv>
   <gid>
    com.test
   </gid>
   <aid>
    console
   </aid>
   <vn>
    1.0
   </vn>
   <bld>
    <plugins>
     <plugin>
      <gid>
       org.apache.maven.plugins
      </gid>
      <aid>
       maven-compiler-plugin
      </aid>
      <vn>
       1.1
      </vn>
      <configuration>
       <source>
        1.0
       </source>
       <target>
        1.0
       </target>
       <showwarnings>
        true
       </showwarnings>
      </configuration>
     </plugin>
    </plugins>
   </bld>
   <dps>
    <dp>
     <gid>
      org.sk
     </gid>
     <aid>
      sk-api
     </aid>
     <vn>
      1.7.20
     </vn>
    </dp>
    <dp>
     <gid>
      org.sk
     </gid>
     <aid>
      sk-log
     </aid>
     <vn>
      SomeValue
     </vn>
    </dp>
   </dps>
  </proj>
 </body>
</html>

您是否尝试使用模块xmltodict将该xml更改为dict,然后再次将其更改为xml?你知道吗

Here is a little guide。你知道吗

And here the repository。你知道吗

这里有一个小函数来替换dict上的元素,当两个键相等时它会有问题,但是对于用不重复的键替换元素,它是可以的,至少对我来说是有效的:

def changes_dict(self, tree, change):
    """Function that changes the values of a json with the keys given
    :param tree: Json to be changed
    :param change: Dictionary with the keys to be changed and the new values: {field1: value1, field2: value2,..., fieldN: valueN}"""
    if isinstance(tree,(list,tuple)):
        res = []
        for subItem in tree:
            result = self.changes_dict(subItem, change)
            res.append(result)
        return res
    elif isinstance(tree,dict):
        for nodeName in tree.keys():
            subTree = tree[nodeName]
            if nodeName in list(change.keys()):
                tree[nodeName] = {'value': str(change[nodeName])}
                change.pop(nodeName)
                if not change:
                    break
            else:
                tree[nodeName] = self.changes_dict(subTree, change)
        return tree
    elif isinstance(tree, str):
        return tree

我制作了这个程序并完成了以下工作:

# -*- coding: utf-8 -*-

import xmltodict, json

def changes_dict(tree, change, wordHelp):
    """Function that changes the values of a json with the keys given
    :param tree: Json to be changed
    :param change: Dictionary with the keys to be changed and the new values: {field1: value1, field2: value2,..., fieldN: valueN}
    :param wordHelp: Word that must be in the values of the dict that contains the change"""
    if isinstance(tree,(list,tuple)):
        res = []
        for subItem in tree:
            result = changes_dict(subItem, change, wordHelp)
            res.append(result)
        return res
    elif isinstance(tree,dict):
        for nodeName in tree.keys():
            subTree = tree[nodeName]
            if nodeName in list(change.keys()) and wordHelp in list(tree.values()):
                tree[nodeName] = {'value': str(change[nodeName])}
                change.pop(nodeName)
                if not change:
                    break
            else:
                tree[nodeName] = changes_dict(subTree, change, wordHelp)
        return tree
    elif isinstance(tree, str):
        return tree

 x = """
 <proj>
    <mV>4.0.0</mV>

        <gId>com.test</gId>
        <aId>console</aId>
        <vn>1.0</vn>

        <bld>
            <plugins>
                <plugin>
                    <gId>org.apache.maven.plugins</gId>
                    <aId>maven-compiler-plugin</aId>
                    <vn>1.1</vn>
                    <configuration>
                        <source>1.0</source>
                        <target>1.0</target>
                        <showWarnings>true</showWarnings>
                    </configuration>
                 </plugin>
             </plugins>
         </bld>
         <dp>
            <gId>org.sk</gId>
            <aId>sk-api</aId>
            <vn>1.7.20</vn>
        </dp>
        <dp>
            <gId>org.sk</gId>
            <aId>sk-log</aId>
            <vn>1.7.25</vn>
        </dp>
    </dps>
</proj> """

dicti = eval(json.dumps(xmltodict.parse(x)))
dicti_changed = changes_dict(dicti, {'vn': 'somevalue'}, 'sk-log')
print(xmltodict.unparse(dicti_changed))

敬礼

相关问题 更多 >

    热门问题