【问题标题】:Parsing pom.xml file with pythin doesn't work in older python versions使用 python 解析 pom.xml 文件在较旧的 python 版本中不起作用
【发布时间】:2020-09-01 12:48:07
【问题描述】:

让我从一个明显的事实开始,我不是 python 开发人员 - 我主要用其他语言编写代码,因此如果对这个问题有“明显”的答案,请原谅。

我编写了一个非常简单的PomParser 类,它应该用作ElementTree 的包装器,并将从pom.xml 文件中返回一些值作为字符串。下面的代码在 Python 3.8 中运行良好,但在 Python >= 3 &&

import xml.etree.ElementTree as ET
import sys
from pathlib import Path


class PomParser:
    data = """<project xmlns="http://maven.apache.org/POM/4.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <groupId>org.example</groupId>
      <scm><connection>scm:git:git://github.com</connection></scm>
    </project>
    """

    tree = None

    namespaces = {'': 'http://maven.apache.org/POM/4.0.0'}

    def __init__(self):
        self.tree = ET.fromstring(self.data)

    def getTree(self):
        return self.tree

    def getGroupId(self):
        return self.findTextByXpath("./groupId")

    def findTextByXpath(self, xpath: str):
        element = self.findByXpath(xpath)
        return element.text if element is not None else None

    def findByXpath(self, xpath: str):
        return self.tree.find(xpath, self.namespaces)

parser = PomParser()
print("Python: ", sys.version)
print("Without defining namespace: ", parser.findTextByXpath("./groupId"))
print("Explicitly defining namespace: ", parser.getTree().findtext("./{http://maven.apache.org/POM/4.0.0}groupId"))

如果您通过 rept.it (example, 它使用 Python 3.8 运行此代码,它将打印:

Python:  3.8.3 (default, May 14 2020, 20:11:43) 
[GCC 7.5.0]
Without defining namespace:  org.example
Explicitly defining namespace:  org.example

但是,如果您在 https://www.onlinegdb.com/online_python_compiler 中运行相同的代码,这似乎是在使用 Python 3.4 - 它会打印:

Python:  3.4.3 (default, Nov 12 2018, 22:25:49)                                                                                                                                                                                                   
[GCC 4.8.4]                                                                                                                                                                                                                                       
Without defining namespace:  None                                                                                                                                                                                                                 
Explicitly defining namespace:  org.example   

我使用 onlinegdb 只是因为它重现了我在 Netlify 中使用相同代码时遇到的问题,其中最新版本是 Python 3.7(实际上是我要添加支持的目标版本)

我想知道我在这里缺少什么? 我是否真的需要在 xpath 过滤器中明确定义命名空间? 如果是这样的话——那么当它什么都不做的时候能够将namespaces定义为一个参数的目的是什么??

【问题讨论】:

    标签: python-3.x xml xpath elementtree


    【解决方案1】:

    这与 Python 3.8 中的更改有关。在该版本中,可以在命名空间映射中使用空字符串作为前缀。这在早期版本中不起作用。

    如果你改变了

    namespaces = {'': 'http://maven.apache.org/POM/4.0.0'}
    

    namespaces = {'p': 'http://maven.apache.org/POM/4.0.0'}
    

    改变

    ./groupId
    

    ./p:groupId
    

    它应该适用于所有版本的 Python 3。

    【讨论】:

    • 我认为这是相关问题:bugs.python.org/issue30485
    • 你的解决方案比我做的更优雅(使用./{url}groupId)!谢谢 - 看起来这为我解决了这个问题! :)
    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 2012-06-15
    • 2022-01-17
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多