如何解析 XML 文件中的 VCARD
How can I parse a VCARD in a XML file
我正在尝试解析一个 XML 文件,其中有一些 VCARD。我需要信息:FN、NOTE(SIREN 和 A)并将它们打印为 FN、SIREN_A 的列表。如果描述中的字符串仅等于 "diviseur"
,我还想将它们添加到列表中
我尝试过不同的东西(vobject、finditer),但 none 都有效。对于我的解析器,我使用的库 xml.etree.ElementTree 和 pandas 通常会导致一些不兼容。
代码python:
import xml.etree.ElementTree as ET
import vobject
newlist=[]
data=[]
data.append(newlist)
diviseur=[]
tree=ET.parse('test_oc.xml')
root=tree.getroot()
newlist=[]
for lifeCycle in root.findall('{http://ltsc.ieee.org/xsd/LOM}lifeCycle'):
for contribute in lifeCycle.findall('{http://ltsc.ieee.org/xsd/LOM}contribute'):
for entity in contribute.findall('{http://ltsc.ieee.org/xsd/LOM}entity'):
vcard = vobject.readOne(entity)
siren = vcard.contents['note'].value,":",vcard.contents['fn'].value
print ('siren',siren.text)
for date in contribute.findall('{http://ltsc.ieee.org/xsd/LOM}date'):
for description in date.findall('{http://ltsc.ieee.org/xsd/LOM}description'):
entite=description.find('{http://ltsc.ieee.org/xsd/LOM}string')
print ('Type entité:', entite.text)
newlist.append(entite)
j=0
for j in range(len(entite)-1):
if entite[j]=="diviseur":
diviseur.append(siren[j])
print('diviseur:', diviseur)
newlist.append(diviseur)
data.append(newlist)
print(data)
xml 要解析的文件:
<?xml version="1.0" encoding="UTF-8"?>
<lom:lom xmlns:lom="http://ltsc.ieee.org/xsd/LOM" xmlns:lomfr="http://www.lom-fr.fr/xsd/LOMFR" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ltsc.ieee.org/xsd/LOM">
<lom:version uniqueElementName="version">
<lom:string language="http://id.loc.gov/vocabulary/iso639-2/fre">V4.1</lom:string>
</lom:version>
<lom:lifeCycle uniqueElementName="lifeCycle">
<lom:contribute>
<lom:entity><![CDATA[
BEGIN:VCARD
VERSION:4.0
FN:Cailler
N:;Valérie;;Mr;
ORG:Veoli
NOTE:SIREN=203025106
NOTE :ISNI=0000000000000000
END:VCARD
]]></lom:entity>
<lom:date uniqueElementName="date">
<lom:dateTime uniqueElementName="dateTime">2019-07-10</lom:dateTime>
<lom:description uniqueElementName="description">
<lom:string>departure</lom:string>
</lom:description>
</lom:date>
</lom:contribute>
<lom:contribute>
<lom:entity><![CDATA[
BEGIN:VCARD
VERSION:4.0
FN:Besnard
N:;Ugo;;Mr;
ORG:MG
NOTE:SIREN=501 025 205
NOTE :A=0000 0000
END:VCARD
]]></lom:entity>
<lom:date uniqueElementName="date">
<lom:dateTime uniqueElementName="dateTime">2019-07-10</lom:dateTime>
<lom:description uniqueElementName="description">
<lom:string>diviseur</lom:string>
</lom:description>
</lom:date>
</lom:contribute>
</lom:lifeCycle>
</lom:lom>
回溯(最后一次调用):
文件 "parser_export_csv_V2.py",第 73 行,位于
vcard = vobject.readOne(实体)
文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 1156 行,在 readOne 中
允许QP))
文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 1089 行,在 readComponents 中
对于 getLogicalLines(stream, allowQP) 中的行,n:
文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 869 行,在 getLogicalLines 中
值 = fp.read(-1)
AttributeError: 'xml.etree.ElementTree.Element' 对象没有属性 'read'
这里有一些问题。
entity
是一个Element
实例,vCard是纯文本数据格式。 vobject.readOne()
需要文本。
XML 文件中的 vCard 属性旁边有不需要的白色space。
NOTE :ISNI=0000000000000000
无效;它应该是 NOTE:ISNI=0000000000000000
(删除了 space)。
vcard.contents['note']
是一个列表,没有 value
属性.
以下代码可能无法完全满足您的需求,但希望对您有所帮助:
import xml.etree.ElementTree as ET
import vobject
NS = {"lom": "http://ltsc.ieee.org/xsd/LOM"}
tree = ET.parse('test_oc.xml')
for contribute in tree.findall('.//lom:contribute', NS):
desc_string = contribute.find('.//lom:string', NS)
print(desc_string.text)
entity = contribute.find('lom:entity', NS)
txt = entity.text.replace(" ", "") # Text with spaces removed
vcard = vobject.readOne(txt)
for p in vcard.contents["note"]:
print(p.name, p.value)
for p in vcard.contents["fn"]:
print(p.name, p.value)
print()
输出:
departure
NOTE SIREN=203025106
NOTE ISNI=0000000000000000
FN Cailler
diviseur
NOTE SIREN=501025205
NOTE A=00000000
FN Besnard
我正在尝试解析一个 XML 文件,其中有一些 VCARD。我需要信息:FN、NOTE(SIREN 和 A)并将它们打印为 FN、SIREN_A 的列表。如果描述中的字符串仅等于 "diviseur"
,我还想将它们添加到列表中我尝试过不同的东西(vobject、finditer),但 none 都有效。对于我的解析器,我使用的库 xml.etree.ElementTree 和 pandas 通常会导致一些不兼容。
代码python:
import xml.etree.ElementTree as ET
import vobject
newlist=[]
data=[]
data.append(newlist)
diviseur=[]
tree=ET.parse('test_oc.xml')
root=tree.getroot()
newlist=[]
for lifeCycle in root.findall('{http://ltsc.ieee.org/xsd/LOM}lifeCycle'):
for contribute in lifeCycle.findall('{http://ltsc.ieee.org/xsd/LOM}contribute'):
for entity in contribute.findall('{http://ltsc.ieee.org/xsd/LOM}entity'):
vcard = vobject.readOne(entity)
siren = vcard.contents['note'].value,":",vcard.contents['fn'].value
print ('siren',siren.text)
for date in contribute.findall('{http://ltsc.ieee.org/xsd/LOM}date'):
for description in date.findall('{http://ltsc.ieee.org/xsd/LOM}description'):
entite=description.find('{http://ltsc.ieee.org/xsd/LOM}string')
print ('Type entité:', entite.text)
newlist.append(entite)
j=0
for j in range(len(entite)-1):
if entite[j]=="diviseur":
diviseur.append(siren[j])
print('diviseur:', diviseur)
newlist.append(diviseur)
data.append(newlist)
print(data)
xml 要解析的文件:
<?xml version="1.0" encoding="UTF-8"?>
<lom:lom xmlns:lom="http://ltsc.ieee.org/xsd/LOM" xmlns:lomfr="http://www.lom-fr.fr/xsd/LOMFR" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ltsc.ieee.org/xsd/LOM">
<lom:version uniqueElementName="version">
<lom:string language="http://id.loc.gov/vocabulary/iso639-2/fre">V4.1</lom:string>
</lom:version>
<lom:lifeCycle uniqueElementName="lifeCycle">
<lom:contribute>
<lom:entity><![CDATA[
BEGIN:VCARD
VERSION:4.0
FN:Cailler
N:;Valérie;;Mr;
ORG:Veoli
NOTE:SIREN=203025106
NOTE :ISNI=0000000000000000
END:VCARD
]]></lom:entity>
<lom:date uniqueElementName="date">
<lom:dateTime uniqueElementName="dateTime">2019-07-10</lom:dateTime>
<lom:description uniqueElementName="description">
<lom:string>departure</lom:string>
</lom:description>
</lom:date>
</lom:contribute>
<lom:contribute>
<lom:entity><![CDATA[
BEGIN:VCARD
VERSION:4.0
FN:Besnard
N:;Ugo;;Mr;
ORG:MG
NOTE:SIREN=501 025 205
NOTE :A=0000 0000
END:VCARD
]]></lom:entity>
<lom:date uniqueElementName="date">
<lom:dateTime uniqueElementName="dateTime">2019-07-10</lom:dateTime>
<lom:description uniqueElementName="description">
<lom:string>diviseur</lom:string>
</lom:description>
</lom:date>
</lom:contribute>
</lom:lifeCycle>
</lom:lom>
回溯(最后一次调用): 文件 "parser_export_csv_V2.py",第 73 行,位于 vcard = vobject.readOne(实体) 文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 1156 行,在 readOne 中 允许QP)) 文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 1089 行,在 readComponents 中 对于 getLogicalLines(stream, allowQP) 中的行,n: 文件 "C:\Users\b\AppData\Local\Programs\Python\Python36-32\lib\site-packages\vobject\base.py",第 869 行,在 getLogicalLines 中 值 = fp.read(-1) AttributeError: 'xml.etree.ElementTree.Element' 对象没有属性 'read'
这里有一些问题。
entity
是一个Element
实例,vCard是纯文本数据格式。vobject.readOne()
需要文本。XML 文件中的 vCard 属性旁边有不需要的白色space。
NOTE :ISNI=0000000000000000
无效;它应该是NOTE:ISNI=0000000000000000
(删除了 space)。vcard.contents['note']
是一个列表,没有value
属性.
以下代码可能无法完全满足您的需求,但希望对您有所帮助:
import xml.etree.ElementTree as ET
import vobject
NS = {"lom": "http://ltsc.ieee.org/xsd/LOM"}
tree = ET.parse('test_oc.xml')
for contribute in tree.findall('.//lom:contribute', NS):
desc_string = contribute.find('.//lom:string', NS)
print(desc_string.text)
entity = contribute.find('lom:entity', NS)
txt = entity.text.replace(" ", "") # Text with spaces removed
vcard = vobject.readOne(txt)
for p in vcard.contents["note"]:
print(p.name, p.value)
for p in vcard.contents["fn"]:
print(p.name, p.value)
print()
输出:
departure
NOTE SIREN=203025106
NOTE ISNI=0000000000000000
FN Cailler
diviseur
NOTE SIREN=501025205
NOTE A=00000000
FN Besnard