简体   繁体   English

解析和操作 Python 的 XML 数据

[英]Parsing and Manipulating XML Data for Python

So I have been struggling with this school project for some time and it is due in the next two days.所以我一直在为这个学校项目苦苦挣扎一段时间,它会在接下来的两天内到期。 I have tried everything from reaching out to other people and scouring online resources for understanding how I am to do this project, but I am thoroughly stumped on how I am to do this.我已经尝试了各种方法,从与其他人联系并搜索在线资源以了解我将如何执行此项目,但我对如何执行此操作感到非常困惑。 We did not cover the material we are to use here in the readings, IE, we didn't read anything about parsing.我们没有涵盖我们在阅读中使用的材料,IE,我们没有阅读任何关于解析的内容。 Any assistance or guidance would be appreciated.任何帮助或指导将不胜感激。 I just need somewhere to look and something to use as I am on my last nerve.我只是需要一个可以看的地方和可以使用的东西,因为我已经迫不及待了。

在此处输入图片说明

Here is my screen if anyone is interested.如果有人感兴趣,这是我的屏幕。 I'll even copy down the instructions and the code for easy copy and pasting if that would be of aid.如果有帮助,我什至会复制说明和代码以便于复制和粘贴。 Please, I just need something.拜托,我只是需要一些东西。

An online plant distributor has recently experience a shortage in its supply of Anemone plants such that the price has increased by 20%. Their plant catalog is maintained in an XML file and they need a Python utility to find the plant by name, read the current price, change it by the specified percentage, and update the file. Writing this utility is your assignment.

Using Python’s ElementTree XML API, write a Python program to perform the following tasks below. Note that your program’s execution syntax must be as follows:

python xmlparse.py plant_catalog.xml plantName percentChange

1.  Using ElementTree, read in this assignments XML file plant_catalog.xml specified by a command line parameter as shown above.
2.  Find the plant by the name passed in as an argument on the command line (plantName above). 
3.  Once found, read the current price and adjust it by the command line argument percentChange. Note that this value could be anything in the range of -90 < percentChange < 100.

For example, if you run your script as follows:

python plant_catalog.xml "Greek Valerian" -20

with the original XML containing:

  <PLANT>
    <COMMON>Greek Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>

The resulting file should contain:

  <PLANT>
    <COMMON>Greek Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>3.48</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>

Note: You may reduce the precision of the calculation if you wish but it isn’t required.

Hints

Since XML is just a text file, you could write the code to read all the data and the decode the XML information. However, I certainly don’t recommend this approach. Instead, let Python do it for you! Using Python’s ElementTree module, parse the file into an “in-memory” representation of the XML data. Once parsed, the root (or starting place) is as simple as requesting it from the tree. Once you have the root, you can call methods to find what you are looking for and modify them appropriately. You'll want to "findall" the plants and, "for" each plant "in" the result, you'll want to compare the name with the name passed on the command line. If you find a match you'll apply the percentage change, save the result back to the tree.

When you are done with the search you will "write" the tree back to a file. I suggest using a different file name or you will be having to re-download the original with each run.

One note of caution, be sure to read about XML in the Distributed Systems text. From doing so and reviewing the data file you will not that there are no attributes in the XML file. Consequently, you do not need to use attribute methods when you attempt this assignment.

The following code snippet will give you a good starting point:

# Calling arguments: plant_catalog.xml plantName percentChange
import xml.etree.ElementTree as ET
import sys

# input parameters
searchName = sys.argv[2]
percent = float(sys.argv[3])

# parse XML data file
tree = ET.parse(sys.argv[1])
root = tree.getroot()

Here is the code I currently have:这是我目前拥有的代码:

import xml.etree.ElementTree as ET
import sys

searchName = sys.argv[2]
percent = float(sys.argv[3])

tree = ET.parse(sys.argv[1])
root = tree.getroot()


def main():
    file = ET.parse("plant_catalog.xml")


if __name__ == "__main__":
    main()

An edit to be made is this is what I have come up with while experimenting with the code one of the nice people here had given me.要进行的编辑是这是我在试验这里一位好人给我的代码时提出的。 It's still not quite working so any help would be appreciated.它仍然不是很有效,所以任何帮助将不胜感激。

在此处输入图片说明

import xml.etree.ElementTree as ET
import sys

searchName = sys.argv[2]
percent = float(3.48)

tree = ET.parse(sys.argv[1])
root = tree.getroot()


def main():
    with open("plant_catalog.xml.xml", "r") as file:
        data = file.read()


for plant in root.findall("PLANT"):
    name = plant.find("COMMON").text

    if name == searchName:
        original_price = float(plant.find("PRICE").text)

with open("plant_catalog - output.xml", "wb") as file:
    file.write(percent)

if __name__ == "__main__":
    main()

I'm not real familiar with elementTree, but looking here it seems like the basic approach is:我对 elementTree 不是很熟悉,但在这里看起来基本的方法是:

for plant in root.findall('PLANT'):
    name = plant.find('COMMON').text
    if name == searchName:
        original_price = float(plant.find('PRICE').text)

Then you can manipulate the price as necessary.然后您可以根据需要操纵价格。

Here is how you find the plant and change the price这是您找到工厂和更改价格的方法

import xml.etree.ElementTree as ET

xml = '''<r> <PLANT>
    <COMMON>Greek Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>  
  <PLANT>
    <COMMON>Other Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>  
  <PLANT>
    <COMMON>Another Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT></r>'''


def change_plant_price(plant_name, new_price):
    root = ET.fromstring(xml)
    plant = root.find(".//*[COMMON='{}']".format(plant_name))
    plant.find('PRICE').text = str(new_price)
    ET.dump(root)


change_plant_price('Greek Valerian', 12.56)

output输出

<r> <PLANT>
    <COMMON>Greek Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>12.56</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>  
  <PLANT>
    <COMMON>Other Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT>  
  <PLANT>
    <COMMON>Another Valerian</COMMON>
    <BOTANICAL>Polemonium caeruleum</BOTANICAL>
    <ZONE>Annual</ZONE>
    <LIGHT>Shade</LIGHT>
    <PRICE>4.36</PRICE>
    <AVAILABILITY>071499</AVAILABILITY>
  </PLANT></r>

Another method.另一种方法。

import sys
from simplified_scrapy import SimplifiedDoc, utils


# No carry
def float2str(f_str, n):
    f_str = str(f_str)
    a, _, c = f_str.partition('.')
    c = (c + "0" * n)[:n]
    return ".".join([a, c])


def main():
    # print(sys.argv)
    xmlFile = sys.argv[1]
    searchName = sys.argv[2]
    percent = float(sys.argv[3]) / 100
    xml = utils.getFileContent(xmlFile)

    doc = SimplifiedDoc(xml)
    plant = doc.getElementByText(searchName, tag='COMMON')
    if plant:
        plant = plant.parent
        price = plant.PRICE # Get price node
        oldPrice = float(price.text)
        newPrice = oldPrice * (1 + percent)
        price.setContent(float2str(newPrice, 2)) # Change price
        # price.setContent('%.2f' % newPrice)
        utils.saveFile(xmlFile, doc.html) # Save file


if __name__ == "__main__":
    main()

Run:跑:

python xmlparse.py plant_catalog.xml "Greek Valerian" -20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM