问题描述
我有如下的ldif文件,我想在这里使用python-ldap包的ldif解析器只提取dn和changetype。
dn: cn=abc,cn=def,cn="dc=grid,dc=mycompany,dc=com",cn=tree,cn=config
changetype: add
objectClass: top
cn: abc
description: myserver
我编写的解析器代码如下:
from ldif import LDIFParser,LDIFRecordList
parser = LDIFRecordList(open("cluster1.ldif","r"))
parser.parse()
for dn,entry in parser.all_records:
print(dn)
print(entry)
但这会读取所有内容并跳过 changetype 键,我不确定是什么原因造成的。有没有更好的方法来解析 ldif 文件?
python -c 'import sys; import ldap; print("\n".join([sys.version,ldap.__version__]))'
2.7.5 (default,May 31 2018,09:41:32)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
2.4.15
解决方法
更新
您似乎在使用非常旧版本的 python-ldap 模块。 2.4.15 版是七年前发布的。当前版本是 3.3.1,如果您pip install python-ldap
,这就是您所获得的。
Python 2 本身于 2020 年 1 月停产,2.7.5 版于 2013 年发布。
您使用的软件很旧,并且有一些错误已在较新的版本中得到修复。你应该升级。
正如我在评论中提到的,我无法重现您所描述的行为。如果我将您的示例 LDIF 内容放入 cluster1.ldif
,我会看到:
>>> from ldif import LDIFParser,LDIFRecordList
>>> parser = LDIFRecordList(open("cluster1.ldif","r"))
>>> parser.parse()
>>> for dn,entry in parser.all_records:
... print(dn)
... print(entry)
...
cn=abc,cn=def,cn="dc=grid,dc=mycompany,dc=com",cn=tree,cn=config
{'changetype': [b'add'],'objectClass': [b'top '],'cn': [b'abc'],'description': [b'myserver']}
>>>
您询问了使用 LDIFRecordList
的替代方法。您当然可以通过子类化 LDIFParser
来编写自己的处理程序,但底层的 LDIF 解析仍然是相同的。这看起来像:
from ldif import LDIFParser,LDIFRecordList
class MyParser(LDIFParser):
def __init__(self,*args,**kwargs):
self.records = []
super().__init__(*args,**kwargs)
def handle(self,dn,entry):
self.records.append((dn,entry))
parser = MyParser(open("cluster1.ldif","r"))
parser.parse()
for dn,entry in parser.records:
print(dn)
print(entry)
...但这实际上只是重新实现LDIFRecordList
,所以我认为您不会从这样做中获得任何好处。
我使用的是 python 3.9.6 和 python-ldap 3.3.1。如果您继续看到不同的行为,您是否会更新您的问题以包含 python -c 'import sys; import ldap; print("\n".join([sys.version,lda p.__version__]))'