使用 python 解析 pom.xml 文件在旧的 python 版本中不起作用

Parsing pom.xml file with pythin doesn't work in older python versions

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

我写了一个非常简单的 PomParser class 它应该用作 ElementTree 的包装器并且 return 来自 pom.xml 文件作为字符串。下面的代码在 Python 3.8 中工作正常,但在 Python >= 3 && < 3.8.

中不起作用
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.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.