尝试使用 python-ldap ldifparser

问题描述

我有如下的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__]))'

的输出