我是一名编程新手,很少使用python,所以请在我尝试解释我想要做的事情时请耐心等待:)
我有以下XML:
<?xml version = "1.0" encoding = "utf-8"?>
<Patients>
<Patient>
<PatientCharacteristics>
<patientCode>3</patientCode>
</PatientCharacteristics>
<Visits>
<Visit>
<DAS>
<CRP>14</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28>20</SWOL28>
<TEN28>20</TEN28>
</Joints>
</DAS>
<VisitDate>2010-02-17</VisitDate>
</Visit>
<Visit>
<DAS>
<CRP>10</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28>15</SWOL28>
<TEN28>20</TEN28>
</Joints>
</DAS>
<VisitDate>2010-02-10</VisitDate>
</Visit>
</Visits>
</Patient>
<Patient>
<PatientCharacteristics>
<patientCode>3</patientCode>
</PatientCharacteristics>
<Visits>
<Visit>
<DAS>
<CRP>14</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28>34</SWOL28>
<TEN28>0</TEN28>
</Joints>
</DAS>
<VisitDate>2010-08-17</VisitDate>
</Visit>
<Visit>
<DAS>
<CRP>10</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28></SWOL28>
<TEN28>2</TEN28>
</Joints>
</DAS>
<VisitDate>2010-07-10</VisitDate>
</Visit>
<Visit>
<DAS>
<CRP>9</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28>56</SWOL28>
<TEN28>6</TEN28>
</Joints>
</DAS>
<VisitDate>2009-07-10</VisitDate>
</Visit>
</Visits>
</Patient>
</Patients>
我想要做的就是更新某些'SWOL28'值,如果它们与我存储在文本文件中的patientCode和VisitDate相匹配。据我所知,elementtree不包含父引用,就好像它一样,我可以从根使用findall()并从那里向后工作。现在这里是我的伪代码:
但是我被困在第5步。如何获得迭代的访问列表?抱歉,如果这是一个非常愚蠢的问题,但我已经高低搜索了我给你的答案!我已将我的代码删除到我需要修复的部分的简单示例:
import xml.etree.ElementTree as ET
tree = ET.parse('DB3.xml')
root = tree.getroot()
for child in root: # THIS GETS ME ALL THE PATIENT ATTRIBUTES
print child.tag
for x in child/Visit: # THIS IS WHAT I CANNOT FIND THE CORRECT SYNTAX FOR
# I WOULD THEN PERFORM STEPS 6, 7 AND 8 HERE
我非常感谢你们对此有任何想法。我不是一个自然而然的编程!
提前致谢, 萨拉
修改1:
根据SVK的建议,我尝试了以下内容:
import xml.etree.ElementTree as ET
tree = ET.parse('Untitled.xml')
root = tree.getroot()
for child in root:
print child.tag
child.find( "visits" )
for x in child.iter("visit"):
print x.tag, x.text
但我得到的唯一输出是: 患者 患者 并没有较低的标签。有什么想法吗?
答案 0 :(得分:5)
您可以直接在元素“元素”下迭代所有“visit”标记,如下所示:
for x in element.iter("visit"):
您可以找到与某个标签匹配的元素的第一个直接子元素:
element.find( "visits" )
看起来您首先必须找到“visits”元素,它是“visit”的父元素,然后遍历其“visit”子元素。将这些放在一起你会有这样的事情:
for patient_element in root:
print patient_element.tag
visits_element = patient_element.find( "visits" )
for visit_element in visits_element.iter("visit"):
print visit_element.tag, visit_element.text
# ... further processing of each visit element here
一般情况下,请查看xml.etree.ElementTree文档中的“查找有趣元素”部分:http://docs.python.org/2/library/xml.etree.elementtree.html#finding-interesting-elements
答案 1 :(得分:4)
这是未经测试的,它应该非常接近你想要的。
for patient in root:
patient_code = patient.find('PatientCharacteristics').find('patientCode')
if patient_code.text == code:
for visit in patient.find('Visits'):
visit_date = visit.find('VisitDate')
if visit_date.text == date:
swol28 = visit.find('DAS').find('Joints').find('SWOL28')
if swol28.text:
visit.find('DAS').find('Joints').set('SWOL28', new_swol28)
答案 2 :(得分:0)
您可以使用CssSelector从Patient元素中获取所需的节点:
from lxml.cssselect import CSSSelector
visitSelector = CSSSelector('Visit')
visits = visitSelector(child)
您也可以这样做以获取patientCode标签和SWOL28标签
然后,您可以使用element.text
答案 3 :(得分:0)
如果您使用lxml.etree
,则可以使用xpath
查找需要更新的元素。
E.g。
doc.xpath('Patient[PatientCharacteristics/patientCode=$patient]/Visits/Visit[VisitDate=$visit]',patient="3",visit="2009-07-10")
所以
from lxml import etree
doc = etree.parse("DB3.xml")
changes = [
dict(patient='3',visit='2010-08-17',swol28="99"),
]
def update_doc(x,d):
for row in d:
for visit in x.xpath('Patient[PatientCharacteristics/patientCode=$patient]/Visits/Visit[VisitDate=$visit]',**row):
for swol28 in visit.xpath('DAS/Joints/SWOL28'):
swol28.text = row['swol28']
update_doc(doc,changes)
print etree.tostring(doc)
应该为您提供包含以下内容的内容:
<Patient>
<PatientCharacteristics>
<patientCode>3</patientCode>
</PatientCharacteristics>
<Visits>
<Visit>
<DAS>
<CRP>14</CRP>
<ESR/>
<Joints>
<DAS_PROFILE>28/28</DAS_PROFILE>
<SWOL28>99</SWOL28>
<TEN28>0</TEN28>
</Joints>
</DAS>
<VisitDate>2010-08-17</VisitDate>
</Visit>
</Visits>
</Patient>