本文介绍了使用 Python 中的条件更新 XML 节点值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的 XML 中,我想解析它并更新PolicyId"的值;到一些随机值,例如POL111112NGJ"和交易日期"到当前日期和时间,仅当它满足条件 PolicyId == POL000002NGJ.我在下面给出的代码更新了PolicyId 和 TransactionDate"的所有值,我只想在条件为 TRUE 时更新该值.根据给定的 XML,我希望将前 3 个集合更新为PolicyId 和 TransactionDate"的相同值.第 4 次设置为不同的值.

In the below XML, I want to parse it and update the value of "PolicyId" to some random value for example "POL111112NGJ" and "TransactionDate" to current date and time ONLY IF IT MEET THE CONDITION PolicyId == POL000002NGJ. Code I given below updates for all values of "PolicyId and TransactionDate", I want to update the value only if condition is TRUE. From the XML given, I expects to update for first 3 sets to same value of "PolicyId and TransactionDate". and 4th set to different value.

我尝试添加条件 ~~~if ROW.attrib['PolicyId'] == 'POL000002NGJ': ~~~ 我得到KeyError: 'PolicyId'"

I tried adding the condition ~~~if ROW.attrib['PolicyId'] == 'POL000002NGJ': ~~~ I gets "KeyError: 'PolicyId'"

有人可以帮我了解如何处理这个问题吗?

Could someone help me understand how to handle this?

--BEFORE UPDATING---

<TABLE>
   <ROW>
      <PolicyId>POL000002NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X1</BusinessCoverageCode>
      <TransactionDate>2020-03-23T10:56:15.00</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>POL000002NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X1</BusinessCoverageCode>
      <TransactionDate>2020-03-23T10:56:15.00</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>POL111111NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X4</BusinessCoverageCode>
      <TransactionDate>2020-03-23T10:56:15.00</TransactionDate>
   </ROW>
</TABLE>


--AFTER UPDATING---

<TABLE>
   <ROW>
      <PolicyId>POL545678NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X1</BusinessCoverageCode>
      <TransactionDate>2020-03-27T10:56:15.00</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>POL545678NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3A2</BusinessCoverageCode>
      <TransactionDate>2020-03-27T10:56:15.00</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>POL111111NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X4</BusinessCoverageCode>
      <TransactionDate>2020-03-23T10:56:15.00</TransactionDate>
   </ROW>
</TABLE>

我正在使用的代码

import xml.etree.ElementTree as ET
from datetime import datetime, timedelta
import random, string

class TimestampUpdater(object):

    def __init__(self, filepath):
        self.meta_file = filepath
        self.tree = ET.parse(r'C:\Users\\XML\python.xml')

    def getMetadataTree(self):
        return self.tree

    def getMetadataRoot(self):
        return self.tree.getroot()
    
    def updatepolicyid(self):
        for ROW in self.getMetadataRoot().findall('ROW'): ##    
            PolicyId = ROW.find('PolicyId')
            
            if ROW.attrib['PolicyId'] == 'POL702965NGJ':
                
                x = 'POL' + ''.join(random.choices(string.digits, k=6)) + 'NGJ'
                PolicyId.text = x
            #PolicyId.set('updated', 'yes')
            self.getMetadataTree().write(self.meta_file)
                   
    
    def updateLastModified(self):
            today = datetime.now()
            for ROW in self.getMetadataRoot().findall('ROW'): ##
                TransactionDate = ROW.find('TransactionDate')
                previous_update = datetime.strptime(TransactionDate.text, '%Y-%m-%dT%H:%M:%S.%f')
                if previous_update < today:
                    TransactionDate.text = today.strftime('%Y-%m-%dT%H:%M:%S.%f')
                    self.getMetadataTree().write(self.meta_file)
                    
                    

def print_file_content(filename):
    """Print contents of a file"""
    with open(filename, 'r') as fh:
        for line in fh:
            print(line.rstrip())

if __name__ == '__main__':
    metafile = 'output.xml'
    print("\n====Before updating:====")
    print_file_content(metafile)
    updater = TimestampUpdater(metafile)
    updater.updateLastModified()
    updater.updatepolicyid() 
    print("\n====After updating:====")
    print_file_content(metafile)

推荐答案

这是一个相对简单的解决方案,但它使用 lxml 而不是 xml.etree.ElementTree.为简单起见,我只专注于更改节点值;显然,您必须根据其他要求采用它.

Here's a relatively simple solution, but one which uses lxml instead of xml.etree.ElementTree. For the sake of simplicity, I just focus exclusively on changing node values; obviously you'll have to adopt it for your other requirements.

policy = """[your xml above]""" #if parsing from an xml string
from lxml import etree

doc = etree.XML(policy.encode()) #if parsing from an xml string
doc = etree.parse(r'path\to\your\file\policy.xml') #if parsing from a file
replacements = ["some random policy number","some random date"]

targets = doc.xpath('//ROW[PolicyId="POL000002NGJ"]')
for target in targets:
    target.xpath('./PolicyId')[0].text = replacements[0]
    target.xpath('.//TransactionDate')[0].text = replacements[1]
print(etree.tostring(doc).decode())
# or to save to a new file:
doc.write('new_policy.xml', pretty_print=True, xml_declaration=True,   encoding="utf-8")

输出:

<TABLE>
   <ROW>
      <PolicyId>some random number</PolicyId>
      <BusinessCoverageCode>COV00002D3X1</BusinessCoverageCode>
      <TransactionDate>some random date</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>some random number</PolicyId>
      <BusinessCoverageCode>COV00002D3X1</BusinessCoverageCode>
      <TransactionDate>some random date</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>some random number</PolicyId>
      <BusinessCoverageCode>COV00002D3X4</BusinessCoverageCode>
      <TransactionDate>some random date</TransactionDate>
   </ROW>
   <ROW>
      <PolicyId>POL111111NGJ</PolicyId>
      <BusinessCoverageCode>COV00002D3X4</BusinessCoverageCode>
      <TransactionDate>2020-03-23T10:56:15.00</TransactionDate>
   </ROW>
</TABLE>

这篇关于使用 Python 中的条件更新 XML 节点值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 21:00