[英]Python Beautiful Soup XML Conditional Query (mixed tags and attributes) Parsing
我有兩個版本的 XML 文件需要從中提取內容。 兩者都具有以下兩種不同格式的相同信息(不僅是不同的標簽,而且是不同的結構):
<activeelementSubstance></activeelementSubstance>
和<inactiveelementSubstance></inactiveelementSubstance>
之間定義了活動和非活動元素<element classCode="IACT"></element classCode="IACT">
和<element classCode="ACTIM"></element classCode="ACTIM">
如何解決這兩種情況以提取 Inactive 和 Active Elements ? (有幾個標簽有同義詞的例子,但我沒有看到任何實際結構與這種情況不同的地方)
我想出了以下代碼(不是很干凈)從第二種情況(提取元素及其代碼)中提取:
activeElements = soup.findAll('Element', attrs={'classCode': 'ACTIM'})
for i in activeElements:
aiName = i.find('name')
aiCode = str(i.find('code'))
print(aiName.text)
print( re.findall(r'"(.*?)"', aiCode)[0] )
print('\nInactive Elements\n')
inactiveElements = soup.findAll('Element', attrs={'classCode': 'IACT'})
for i in inactiveElements:
aiName = i.find('name')
print(aiName.text)
aiCode = i.find('code')['code']
print(aiCode)
XML 文件的示例如下:
第一種類型(格式為<element classCode="IACT"></element classCode="IACT">
和<element classCode="ACTIM"></element classCode="ACTIM">
):
<?xml version="1.0" encoding="UTF-8"?>
<document>
<manufacturedProduct>
<element classCode="IACT">
<elementSubstance>
<code code="36SFW2JZ" codeSystem="33590coding"/>
<name>HYPROMELLOSE 2910 (15 MPA.S)</name>
</elementSubstance>
</element>
<element classCode="IACT">
<elementSubstance>
<code code="70097M6I" codeSystem="33590coding"/>
<name>MAGNESIUM STEARATE</name>
</elementSubstance>
</element>
<elementSubstance>
<code code="XHX3C3X6" codeSystem="33590coding"/>
<name>TRIACETIN</name>
</elementSubstance>
</element>
<element classCode="ACTIM">
<quantity>
<numerator unit="mg" value="250"/>
<denominator unit="1" value="1"/>
</quantity>
<elementSubstance>
<code code="JTE4MNN1" codeSystem="33590coding"/>
<name>AZITHROMYCIN MONOHYDRATE</name>
</elementSubstance>
</element>
</manufacturedProduct>
</document>
第二種類型(格式為<activeelementSubstance></activeelementSubstance>
和<inactiveelementSubstance></inactiveelementSubstance>
):
<?xml version="1.0" encoding="UTF-8"?>
<document>
<manufacturedProduct>
<activeelementSubstance>
<code code="VB0R961H" codeSystem="33590coding" codeSystemName="USDA" />
<name>Prednisone</name>
</activeelementSubstance>
</activeelement>
<inactiveelement>
<inactiveelementSubstance>
<code code="776XM704" codeSystem="33590coding" codeSystemName="USDA" />
<name>calcium stearate</name>
</inactiveelementSubstance>
</inactiveelement>
<inactiveelement>
<inactiveelementSubstance>
<name>corn starch</name>
</inactiveelementSubstance>
</inactiveelement>
</manufacturedProduct>
</document>
XML 文件嵌套很深(這也是我使用 Beautiful soup 的部分原因),我嘗試清理並提取它們的相關部分。
您可以在 CSS 選擇器列表中使用 CSS OR 語法,而不是添加條件邏輯來確定分配提取結果的位置。 下面可以通過重構來減少嵌套,例如將某些部分移動到它們自己的函數中,但它提供了一個起點。
from bs4 import BeautifulSoup as bs
type_1 = '''
<?xml version="1.0" encoding="UTF-8"?>
<document>
<manufacturedProduct>
<element classCode="IACT">
<elementSubstance>
<code code="36SFW2JZ" codeSystem="33590coding"/>
<name>HYPROMELLOSE 2910 (15 MPA.S)</name>
</elementSubstance>
</element>
<element classCode="IACT">
<elementSubstance>
<code code="70097M6I" codeSystem="33590coding"/>
<name>MAGNESIUM STEARATE</name>
</elementSubstance>
</element>
<elementSubstance>
<code code="XHX3C3X6" codeSystem="33590coding"/>
<name>TRIACETIN</name>
</elementSubstance>
</element>
<element classCode="ACTIM">
<quantity>
<numerator unit="mg" value="250"/>
<denominator unit="1" value="1"/>
</quantity>
<elementSubstance>
<code code="JTE4MNN1" codeSystem="33590coding"/>
<name>AZITHROMYCIN MONOHYDRATE</name>
</elementSubstance>
</element>
</manufacturedProduct>
</document>'''
type_2 = '''
<?xml version="1.0" encoding="UTF-8"?>
<document>
<manufacturedProduct>
<activeelementSubstance>
<code code="VB0R961H" codeSystem="33590coding" codeSystemName="USDA" />
<name>Prednisone</name>
</activeelementSubstance>
</activeelement>
<inactiveelement>
<inactiveelementSubstance>
<code code="776XM704" codeSystem="33590coding" codeSystemName="USDA" />
<name>calcium stearate</name>
</inactiveelementSubstance>
</inactiveelement>
<inactiveelement>
<inactiveelementSubstance>
<name>corn starch</name>
</inactiveelementSubstance>
</inactiveelement>
</manufacturedProduct>
</document>'''
results = {'active': [], 'inactive': []}
for doc in [type_1, type_2]:
soup = bs(doc, 'lxml')
for i in soup.select('[classcode=IACT], [classcode=ACTIM], activeelement, inactiveelement'):
if i.get('classcode') == 'IACT' or i.name == 'inactiveelement':
try:
d = {i.select_one('name').text:i.select_one('code')['code']}
except:
d = {i.select_one('name').text:'missing'}
results['inactive'].append(d)
else:
results['active'].append({i.select_one('name').text:i.select_one('code')['code']})
print(results)
您可以將 CSS 選擇器與,
一起使用。 例如:
from bs4 import BeautifulSoup
xml_doc1 = ...version 1 of the xml document...
xml_doc2 = ...version 2 of the xml document...
soup = BeautifulSoup(xml_doc1 + xml_doc2, "html.parser")
elem = soup.select(
'element[classCode="IACT"], element[classCode="ACTIM"], activeelementSubstance, inactiveelementSubstance'
)
for e in elem:
code = c["code"] if (c := e.code) else "-"
name = n.text if (n := e.find("name")) else "-"
print(code, name)
印刷:
36SFW2JZ HYPROMELLOSE 2910 (15 MPA.S)
70097M6I MAGNESIUM STEARATE
JTE4MNN1 AZITHROMYCIN MONOHYDRATE
VB0R961H Prednisone
776XM704 calcium stearate
- corn starch
或分為活動和非活動:
print("Active Elements")
elem = soup.select('element[classCode="ACTIM"], activeelementSubstance')
for e in elem:
code = c["code"] if (c := e.code) else "-"
name = n.text if (n := e.find("name")) else "-"
print(code, name)
print("\nInactive Elements")
elem = soup.select('element[classCode="IACT"], inactiveelementSubstance')
for e in elem:
code = c["code"] if (c := e.code) else "-"
name = n.text if (n := e.find("name")) else "-"
print(code, name)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.