小能豆

Python 3.4:如何进行 xml 验证

py

我正在尝试在 Python 中针对某些 XSD 进行 XML 验证。我使用 lxml 包成功了。但是当我尝试将代码移植到 Python 3.4 时,问题就开始了。我尝试安装 3.4 版本的 lxml。看来我的企业 Linux 与 lxml 配合得不是很好。

pip installation:

pip install lxml
Collecting lxml
  Downloading lxml-3.4.4.tar.gz (3.5MB)
    100% |################################| 3.5MB 92kB/s
Installing collected packages: lxml
  Running setup.py install for lxml
Successfully installed lxml-3.4.4

After pip Installation :

> python
Python 3.4.1 (default, Nov 12 2014, 13:34:29)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /ws/satjonna-sjc/pyats/lib/python3.4/site-packages/lxml/etree.cpython-34m.so: undefined symbol: xmlMemDisplayLast
>>>

git installation:

git clone git://github.com/lxml/lxml.git lxml
Cloning into 'lxml'...
remote: Counting objects: 25078, done.
remote: Total 25078 (delta 0), reused 0 (delta 0), pack-reused 25078
Receiving objects: 100% (25078/25078), 21.38 MiB | 2.66 MiB/s, done.
Resolving deltas: 100% (9854/9854), done.
Checking connectivity... done.

After git Installation :

> python
Python 3.4.1 (default, Nov 12 2014, 13:34:29)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'etree'

我找到了 lxml 等效的xml.etree.ElementTree。但主要问题是除了重写整个代码之外,我还需要找到 lxml 验证方法 ( *etree.fromstring(xmlstring, xmlparser)* ) 的 xml.etree 替代方案。任何使这项工作可行的建议都将非常有帮助。


阅读 8

收藏
2024-12-18

共1个答案

小能豆

在尝试解决你的问题之前,我们需要理解几个关键点。看起来你在企业 Linux 系统上遇到了环境问题,这可能与以下原因有关:

  1. lxml 的依赖库lxml 依赖于 libxml2 和 libxslt。这些库的版本如果过旧或不兼容,会导致类似错误。
  2. Python 版本和编译器版本:你正在使用 Python 3.4,这个版本较旧,可能需要特定的编译器支持。

如果你不能升级系统或相关工具,可以尝试以下解决方案:


解决方案 1:检查 libxml2 和 libxslt 的版本

运行以下命令,查看系统安装的 libxml2libxslt 版本:

xml2-config --version
xslt-config --version

确保版本符合 lxml 的要求(libxml2 >= 2.9.2libxslt >= 1.1.27)。如果版本过旧,可以尝试下载和编译更新的版本:

wget ftp://xmlsoft.org/libxml2/libxml2-2.9.12.tar.gz
tar -xvzf libxml2-2.9.12.tar.gz
cd libxml2-2.9.12
./configure --prefix=/usr/local
make
sudo make install

wget ftp://xmlsoft.org/libxslt/libxslt-1.1.34.tar.gz
tar -xvzf libxslt-1.1.34.tar.gz
cd libxslt-1.1.34
./configure --prefix=/usr/local --with-libxml-prefix=/usr/local
make
sudo make install

然后重新安装 lxml

pip install --no-cache-dir --force-reinstall lxml

解决方案 2:使用静态编译版本安装 lxml

如果无法升级系统的依赖库,可以安装静态编译版本的 lxml。通过以下命令安装:

pip install lxml --no-binary=lxml

这将强制 pip 在本地构建 lxml,并使用你的环境中现有的依赖项。


解决方案 3:使用备用 XML 解析库

如果无法让 lxml 正常工作,可以考虑使用 Python 内置的 xml.etree.ElementTree 或其他兼容的库,例如 xmlschemadefusedxml

使用 xmlschema 验证 XML

xmlschema 是一个纯 Python 实现的 XML Schema 验证库,可以替代 lxml 的验证功能:

import xmlschema

# 加载 XSD 文件
schema = xmlschema.XMLSchema("schema.xsd")

# 验证 XML 数据
xml_data = "data.xml"
if schema.is_valid(xml_data):
    print("XML is valid")
else:
    print("XML is invalid")

使用 xml.etree.ElementTree

虽然 xml.etree.ElementTree 没有直接的 XSD 验证功能,但可以解析 XML:

import xml.etree.ElementTree as ET

tree = ET.parse('data.xml')
root = tree.getroot()

# 直接访问节点
for child in root:
    print(child.tag, child.attrib)

解决方案 4:使用容器化解决依赖问题

如果升级依赖和库仍然有困难,可以考虑使用 Docker 来隔离环境:

  1. 创建一个包含正确依赖的 Docker 容器:
    dockerfile FROM python:3.4-slim RUN apt-get update && apt-get install -y libxml2-dev libxslt-dev RUN pip install lxml

  2. 构建并运行容器:
    bash docker build -t python-lxml . docker run -it --rm python-lxml


最终建议

  • 如果你必须保留 Python 3.4:尝试解决依赖版本问题,或者使用 Docker 容器化。
  • 如果可以升级 Python:升级到受支持的 Python 版本(如 3.10+),以简化依赖管理。
  • 如果必须迁移到其他库xmlschema 是对 lxml 的良好替代,用于 XML Schema 验证。

如果这些方法无法解决问题,请提供更多具体的错误日志或环境信息以进一步诊断!

2024-12-18