python - 使用 BeautifulSoup 无法按预期解析 XML

标签 python xml python-2.7 xml-parsing beautifulsoup

我正在尝试从网站解析 XML。如果内容格式不正确,我将无法控制。下面是一个非常简化的 XML 数据示例。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items:items itemId="1">
    <parameter name="param1" value="A"/>
    <parameter name="param2" value="B"/>
    <product productid="test1">
        <parameter name="prodinfo1" value="Q"/>
        <parameter name="prodinfo2" value="R"/>
    </product>
    <product productid="test2">
        <parameter name="prodinfo1" value="S"/>
        <parameter name="prodinfo2" value="T"/>
    </product>
</items:items>
<items:items itemId="2">
    <parameter name="param1" value="C"/>
    <parameter name="param2" value="D"/>
    <product productid="test3">
        <parameter name="prodinfo1" value="U"/>
        <parameter name="prodinfo2" value="V"/>
    </product>
    <product productid="test4">
        <parameter name="prodinfo1" value="W"/>
        <parameter name="prodinfo2" value="X"/>
    </product>
</items:items>

我使用 BeautifulSoup 3.2.1 编写了一个简短的 Python 2.7 脚本来解析 XML(我仅限于使用这些版本,因此不幸的是,无法升级)。

from BeautifulSoup import BeautifulStoneSoup

def main():
    fieldList = ('param1','param2')
    prodFieldList = ('prodinfo1','prodinfo2')
    xmlfile = 'test.xml'
    xmldata = open(xmlfile).read()
    soup = BeautifulStoneSoup(xmldata)
    print soup.prettify()

    for message in soup.findAll('items:items', recursive=False):
        report = {}
        for field in fieldList:
            report[field] = '{}'.format(message.find(attrs={"name" : field})['value'])
        for product in message.findAll('product', recursive=False):
            prodreport = {}
            for field in prodFieldList:
                prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value'])

if __name__ == "__main__":
    main()

由于某种原因,<product></product>内的参数例如 prodinfo1 和 prodinfo2 不会显示。当我查看 soup.prettify() 的输出时,而不是像上面的 XML 文件中显示的那样缩进,我可以看到产品参数列在 <product></product> 之外。标签,因此它们与特定产品的身份丢失了:

<?xml version='1.0' encoding='utf-8'?>
<items:items itemid="1">
 <parameter name="param1" value="A">
 </parameter>
 <parameter name="param2" value="B">
  <product productid="test1">
  </product>
 </parameter>
 <parameter name="prodinfo1" value="Q">
 </parameter>
 <parameter name="prodinfo2" value="R">
  <product productid="test2">
  </product>
 </parameter>
 <parameter name="prodinfo1" value="S">
 </parameter>
 <parameter name="prodinfo2" value="T">
 </parameter>
</items:items>
<items:items itemid="2">
 <parameter name="param1" value="C">
 </parameter>
 <parameter name="param2" value="D">
  <product productid="test3">
  </product>
 </parameter>
 <parameter name="prodinfo1" value="U">
 </parameter>
 <parameter name="prodinfo2" value="V">
  <product productid="test4">
  </product>
 </parameter>
 <parameter name="prodinfo1" value="W">
 </parameter>
 <parameter name="prodinfo2" value="X">
 </parameter>
</items:items>

我一直在寻找,但没有发现有同样问题的人。为什么会发生这种情况?我该如何正确解析此 XML?感谢您抽出时间。

最佳答案

进行 3 次更改后,它对我有用:

  • 0) 我正在使用 bs4(这是我安装的唯一版本)

  • 1) BeautifulSoup(xmldata, features="xml") 而不是 BeautifulStoneSoup(xmldata)BeautifulStoneSoup 的折旧时间为BS4

  • 2) 我将 soup.findAll('items:items', recursive=False) 更改为 soup.findAll(True, {"itemId":True}, recursive =假)

    from bs4 import BeautifulSoup
    
    xmldata = #load your data 
    
    if __name__ == "__main__":
    
        fieldList = ('param1','param2')
        prodFieldList = ('prodinfo1','prodinfo2')
        soup = BeautifulSoup(xmldata, features="xml")# <- notice this
        print soup.prettify(), "\n"
    
        for message in soup.findAll(True, {"itemId":True}, recursive=False):# <- and this
    
            report = {}
            for field in fieldList:
                report[field] = '{}'.format(message.find(attrs={"name" : field})['value'])
                print report
    
            for product in message.findAll('product', recursive=False):
                prodreport = {}
                for field in prodFieldList:
                    prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value'])
                print prodreport
    

输出:

    <?xml version="1.0" encoding="utf-8"?>
    <items itemId="1">
     <parameter name="param1" value="A"/>
     <parameter name="param2" value="B"/>
     <product productid="test1">
      <parameter name="prodinfo1" value="Q"/>
      <parameter name="prodinfo2" value="R"/>
     </product>
     <product productid="test2">
      <parameter name="prodinfo1" value="S"/>
      <parameter name="prodinfo2" value="T"/>
     </product>
    </items> 

    {'param1': 'A'}
    {'param2': 'B', 'param1': 'A'}
    {'prodinfo1': 'Q', 'prodinfo2': 'R'}
    {'prodinfo1': 'S', 'prodinfo2': 'T'}

关于python - 使用 BeautifulSoup 无法按预期解析 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31621456/

相关文章:

python - 在 AWS Lambda 中使用 numpy

java - 使用 spring 4 将属性文件中的占位符替换为传递的 VM 参数(-D params)

java - 如何使用 JUnit 和 Maven Surefire 插件将数据添加到测试用例

xml - Golang Google 警报 XML 解析

python - 在 Odoo 8 ORM api 中,如何使用 search() 以相反的顺序获取结果?

Python多处理安全地写入文件

Python字典格式

python [:] notation and range

python - 是否检查编写的代码是否在 python 2.7 或 3 及更高版本中?

python - python 根据另一个列值将多列转换为单列