Je suis un novice en programmation et n'utilise que rarement python, alors s'il vous plaît, supportez-moi pendant que j'essaie d'expliquer ce que j'essaie de faire :)
J'ai le XML suivant:
<?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>
Tout ce que je veux faire ici, c'est mettre à jour certaines valeurs 'SWOL28' si elles correspondent aux codes patientCode et VisitDate que j'ai enregistrés dans un fichier texte. Si j'ai bien compris, elementtree n'inclut pas de référence parent, comme si c'était le cas, je pourrais simplement utiliser findall () à partir de la racine et travailler à l'envers à partir de là. En l'état, voici mon psuedocode:
Mais je suis bloqué à l'étape 5. Comment puis-je obtenir une liste des visites à parcourir? Toutes mes excuses si c'est une question très stupide, mais j'ai cherché haut et bas pour une réponse, je vous assure! J'ai réduit mon code à l'exemple de la partie à corriger ci-dessous:
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
Je serais profondément reconnaissant de toute idée que chacun de vous pourrait avoir à ce sujet. Je ne suis pas une programmation naturelle, c'est sûr!
Merci d'avance, Sarah
Modifier 1:
Sur les conseils de SVK ci-dessous, j'ai essayé les solutions suivantes:
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
Mais le seul résultat que je reçois est: Patient Patient Et aucune des balises inférieures. Des idées?
Cela n'a pas été testé, cela devrait être assez proche de ce que vous voulez.
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)
Vous pouvez parcourir toutes les balises "visit" directement sous un élément "element" comme ceci:
for x in element.iter("visit"):
Vous pouvez trouver le premier enfant direct de l'élément correspondant à une balise donnée avec:
element.find( "visits" )
Il semble que vous deviez d'abord localiser l'élément "visites", qui est le parent de "visite", puis parcourir les enfants "visiter". En les réunissant, vous obtiendrez quelque chose comme ceci:
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
De manière générale, consultez la section "Recherche d'éléments intéressants" dans la documentation de xml.etree.ElementTree: http://docs.python.org/2/library/xml.etree.elementtree.html#finding-interesting-elements
Vous pouvez utiliser un CssSelector pour obtenir les nœuds souhaités à partir de l'élément Patient:
from lxml.cssselect import CSSSelector
visitSelector = CSSSelector('Visit')
visits = visitSelector(child)
vous pouvez faire de même pour obtenir les balises patientCode et SWOL28 . Vous pouvez ensuite accéder au texte des éléments et le modifier à l'aide de element.text
.
Si vous utilisez lxml.etree
, vous pouvez utiliser xpath
pour rechercher les éléments à mettre à jour.
Par exemple.
doc.xpath('Patient[PatientCharacteristics/patientCode=$patient]/Visits/Visit[VisitDate=$visit]',patient="3",visit="2009-07-10")
Alors
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)
Devrait vous donner quelque chose qui contient:
<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>