Delphi 7 reading and processing xml file how and which component - update

I have a client that supplies a file with mixed data, separated by commas, and xml. Separated comma is not a problem, but xml is new to me.

I tried to find the component in order to do what I needed (omnixml - abandoned - using delphi built into the xml component ), maybe ...

I have the following data:

<Passengers> <Passenger> <No>1</No> <Title>mrs</Title> <ForeName>Anne</ForeName> <SurName>XXXXXXXX</SurName> <Age>33</Age> <UWStatus>accept</UWStatus> <Screening> <ScreeningData> <ScreeningPath SL="2.2" DATA="1"> <MedicalRisk>4.01</MedicalRisk> <rootConditionId>1292</rootConditionId> <isAMT>false</isAMT> <regionId>4</regionId> <isWinterSport>false</isWinterSport> <isRetScheme>false</isRetScheme> <isPair>false</isPair> <LinkedCondition>3</LinkedCondition> <LinkedConditions> <LinkedCondition Name="High blood pressure" ICD="401.9" Type="D"/> <LinkedCondition Name="Renal failure" ICD="586" Type="D"/> <LinkedCondition Name="Abdominal aortic aneurysm" ICD="441.4" Type="I"/> <LinkedCondition Name="Peripheral vascular disease" ICD="443.9" Type="I"/> <LinkedCondition Name="Angina" ICD="414.9" Type="IS"/> <LinkedCondition Name="Enlarged heart" ICD="425" Type="IS"/> <LinkedCondition Name="Heart attack" ICD="414.9" Type="IS"/> <LinkedCondition Name="Heart failure" ICD="428.0" Type="IS"/> <LinkedCondition Name="Mini stroke" ICD="435.9" Type="IS"/> <LinkedCondition Name="Stroke" ICD="434" Type="IS"/> </LinkedConditions> <ScreeningHistory> <DeclaredCondition Score="3.56"> <conditions> <Condition> <id>1292</id> <parentid>-1</parentid> <name>Epilepsy</name> <questions> <Question> <id>1</id> <Text>If awake#$ do you normally lose consciousness during a fit/seizure?</Text> <currentAnswer> <Text>Yes</Text> <id>1</id> </currentAnswer> </Question> <Question> <id>2</id> <Text>How many fits/seizures causing loss of consciousness have you had in the last four weeks?</Text> <currentAnswer> <Text>0</Text> <id>1</id> </currentAnswer> </Question> <Question> <id>3</id> <Text>How many fits/seizures causing loss of consciousness have you had in the last six months?</Text> <currentAnswer> <Text>0</Text> <id>1</id> </currentAnswer> </Question> <Question> <id>4</id> <Text>How many unplanned hospital admissions have you had for epilepsy/seizures in the last year?</Text> <currentAnswer> <Text>1</Text> <id>2</id> </currentAnswer> </Question> <Question> <id>5</id> <Text>How many different medicines do you take for your epilepsy/seizures?</Text> <currentAnswer> <Text>1</Text> <id>2</id> </currentAnswer> </Question> <Question> <id>6</id> <Text>How long ago was your first fit/seizure?</Text> <currentAnswer> <Text>6 to 12 months ago</Text> <id>2</id> </currentAnswer> </Question> <Question> <id>7</id> <Text>If not already declared to us#$ is your epilepsy/seizures caused by:</Text> <currentAnswer> <Text>None of these</Text> <id>4</id> </currentAnswer> </Question> </questions> <currentQuestionId>7</currentQuestionId> <isAMTExclusion>false</isAMTExclusion> <isWSExclusion>false</isWSExclusion> <Score>3.56</Score> <ICD>345.9</ICD> <Deterioration>0</Deterioration> <isOkForWS>true</isOkForWS> <isOkForAMT>true</isOkForAMT> <exclusionType>None</exclusionType> </Condition> </conditions> </DeclaredCondition> <DeclaredCondition Score="1.45"> <conditions> <Condition> <id>1332</id> <parentid>-1</parentid> <name>Blood pressure</name> <questions> <Question> <id>1</id> <Text>How many medicines does your doctor advise you to take for high blood pressure?</Text> <currentAnswer> <Text>1</Text> <id>2</id> </currentAnswer> </Question> <Question> <id>2</id> <Text>Has your dose been increased or have you been prescribed a new tablet in the last six months?</Text> <currentAnswer> <Text>No</Text> <id>2</id> </currentAnswer> </Question> <Question> <id>3</id> <Text>Have you been advised to take a medication to lower your cholesterol level?</Text> <currentAnswer> <Text>No</Text> <id>1</id> </currentAnswer> </Question> <Question MQ="2"> <id>4</id> <Text>Have you ever been a smoker?</Text> <currentAnswer> <Text>Yes - gave up less than a year ago</Text> <id>3</id> </currentAnswer> </Question> </questions> <currentQuestionId>4</currentQuestionId> <isAMTExclusion>false</isAMTExclusion> <isWSExclusion>false</isWSExclusion> <Score>1.45</Score> <ICD>401.9</ICD> <Deterioration>1</Deterioration> <isOkForWS>true</isOkForWS> <isOkForAMT>true</isOkForAMT> <exclusionType>None</exclusionType> <LinkedConditions> <LinkedCondition Name="High blood pressure" ICD="401.9" Type="D"/> <LinkedCondition Name="Renal failure" ICD="586" Type="D"/> <LinkedCondition Name="Abdominal aortic aneurysm" ICD="441.4" Type="I"/> <LinkedCondition Name="Peripheral vascular disease" ICD="443.9" Type="I"/> <LinkedCondition Name="Angina" ICD="414.9" Type="IS"/> <LinkedCondition Name="Enlarged heart" ICD="425" Type="IS"/> <LinkedCondition Name="Heart attack" ICD="414.9" Type="IS"/> <LinkedCondition Name="Heart failure" ICD="428.0" Type="IS"/> <LinkedCondition Name="Mini stroke" ICD="435.9" Type="IS"/> <LinkedCondition Name="Stroke" ICD="434" Type="IS"/> </LinkedConditions> </Condition> </conditions> </DeclaredCondition> </ScreeningHistory> </ScreeningPath> </ScreeningData> </Screening> 

The xml all in one field does not contain spaces (I formatted it), and where there is more than one person, it looks like a new passenger entry.

I need to be able to handle this and retrieve things like

The name / fields of the first / last name from the passenger’s record and then from and from the branch and which refers to it is repeated for each answer to each condition.

I think this is pretty easy, but I'm struggling.

The code that I still have ...

Is the first person right, the second will lose one of his brothers and sisters? Is there a mistake or is it me?

 StartItemNode:=XMLDoc.DocumentElement.ChildNodes.First; ANode := StartItemNode; repeat Title := ANode.ChildNodes['Title'].Text; Forename := ANode.ChildNodes['ForeName'].Text; Surname := ANode.ChildNodes['SurName'].Text; Age:=Anode.ChildNodes['Age'].Text; memo1.Lines.Add(Title+' '+Forename+' '+Surname+' '+Age); CNode:=Anode.ChildNodes.FindNode('Screening'); CNode:=CNode.ChildNodes.FindNode('ScreeningData'); CNode:=CNode.ChildNodes.FindNode('ScreeningPath'); CNode:=CNode.ChildNodes.FindNode('ScreeningHistory'); CNode:=Cnode.ChildNodes.FindNode('DeclaredCondition'); CNode:=Cnode.ChildNodes.FindNode('conditions'); CNode:=Cnode.ChildNodes.FindNode('Condition'); (* Missing the 2nd illness on the 2nd node - but why *) repeat ill:=Cnode.ChildNodes['name'].text; memo1.Lines.add(ill); Unode:=Cnode; CNode:=Cnode.NextSibling; until cnode=nil; 

Any help would be greatly appreciated please. Regards Phil

+4
source share
5 answers

We used TurboPower XML partner extensively in older versions of Delphi. (I don’t remember if we used it in Delphi 7). Here is a link to the latest version of SourceForge: http://sourceforge.net/projects/tpxmlpartner/ . You can find the previous version that will work for you.

You can also use the xml com object found in msxml.dll. It works very well. Here's more info on this: fooobar.com/questions/1392926 / .... Apparently, "The TXMLDocument object (for delphi 7) located in XMLDoc.pas is a Wrapper version of MSXML 4 o less.". But if you import version 6, you should be in good shape.

+2
source

I really enjoy using NativeXML with SimDesign. It has decent documents and is open source. http://www.simdesign.nl/nativexml.html

+2
source

You do not need a separate library: Delphi comes with one already

Create an interface module for your (non-attached) XML file using the XML Data Binding Wizard (for D7 only in the corporate version), see File> New> Other> New> Link XML Data. Adjust as you like, but just pass each page of the wizard by clicking OK, it works fine by default. (Note that the default settings for other versions of Delphi may differ from the default settings.) Although the only thing I personally need to get rid of is the Type suffix for each type of interface. (As well as for class type names, but this is not an option in the wizard, so you can do it manually.)

See this answer as an example or for more instructions.

Please note that this wizard is for convenience only: you can also use only TXMLDocument (on the Internet tab of the component palette). Get the root node using ADocument.DocumentElement , get the child nodes with Node.ChildNodes.FindNode('Node name') and its values ​​using Node.ChildValues['Value name'] .

+2
source

For TXmlDocument, Msxml is built into D7 (or D6, as I use roughly the same thing).

There is also an old version of the built-in Dieter Köhler XDOM, or you can download its updated ADOM from www.philo.de/xml/ (with the IDomNode cover from github.com/Midiar/adomxmldom). They are implemented in Pascal - good for debugging. ADOM provides you with XPath functionality.

Edit: Msxml also has XPath (as well as XSLT).

+1
source

I fixed the problem and used Delphi7 built into the XML object. And for a few people.

It was a lot harder than I thought.

As in the above structure, I found that if you stated your health condition, everything was fine, but if this condition is implied, for example, you have high blood pressure, so you may have high cholesterol (spelling!), Then the subsequent question is not under the basic declared conditions, but on the conditions.

The following code works for this - there is most of the repeated quote, but I wanted it to work, and not look beautiful.

And I have to admit that I learned more about XML than I wanted LOL ... And big thaks :-) for all the help offered - a lot of reading on stack overflow and some search queries, and now I have the result!

 procedure TForm1.Button1Click(Sender: TObject); var StartItemNode:IXMLNode; ANode:IXMLNode; CNode:IXMLNode; LNode:IXMLNode; QNode:IXMLNode; UNode:IXMLNode; hnode:ixmlnode; INode:IXMLNode; number:widestring; Title:widestring; Forename:widestring; Surname:widestring; Age:widestring; ill:widestring; quest:widestring; answer:widestring; first:boolean; who:string; begin opendialog1.Execute; who:=extractfilepath(opendialog1.FileName)+extractfilename(opendialog1.filename) +'_TXT.TXT'; XMLDOC.FileName:=opendialog1.FileName; XMLDoc.Active:=True; memo1.Clear; XMLDOC.SaveToFile('c:\philxx.xml'); StartItemNode:=XMLDoc.DocumentElement.ChildNodes.First; ANode := StartItemNode; memo1.Lines.add('Filename '+opendialog1.FileName); if anode<>nil then begin repeat memo1.Lines.Add('====== New Person ======'); number :=anode.childnodes['number'].Text; Title := ANode.ChildNodes['Title'].Text; Forename := ANode.ChildNodes['ForeName'].Text; Surname := ANode.ChildNodes['SurName'].Text; Age:=Anode.ChildNodes['Age'].Text; memo1.lines.add(number); memo1.Lines.Add(Title+' '+Forename+' '+Surname+' '+Age); CNode:=Anode.ChildNodes.FindNode('Screening'); CNode:=CNode.ChildNodes.FindNode('ScreeningData'); CNode:=CNode.ChildNodes.FindNode('ScreeningPath'); CNode:=CNode.ChildNodes.FindNode('ScreeningHistory'); HNode:=Cnode.ChildNodes.FindNode('DeclaredCondition'); while hnode<>nil do begin unode:=hnode; memo1.lines.add('==== Illnesses ==='); if unode<>nil then begin UNode:=Unode.ChildNodes.FindNode('conditions'); Cnode:=Unode; Inode:=CNode.ChildNodes.FindNode('Condition'); while unode<>nil do begin ill:=Inode.ChildNodes['name'].text; memo1.Lines.add(ill); lnode:=Unode; unode:=unode.nextsibling; if unode=nil then begin unode:=lnode; inode:=inode.NextSibling; if inode=nil then unode:=nil; end else begin CNode:=Unode.ChildNodes.FindNode('conditions'); Inode:=CNode.ChildNodes.FindNode('Condition'); end; end; end; hnode:=hnode.nextsibling; end; CNode:=Anode.ChildNodes.FindNode('Screening'); CNode:=CNode.ChildNodes.FindNode('ScreeningData'); CNode:=CNode.ChildNodes.FindNode('ScreeningPath'); CNode:=CNode.ChildNodes.FindNode('ScreeningHistory'); HNode:=Cnode.ChildNodes.FindNode('DeclaredCondition'); while hnode<>nil do begin unode:=hnode; (* Gets all the questions but seems to have same issue with missing questions for 2nd illness *) if unode<>nil then begin UNode:=Unode.ChildNodes.FindNode('conditions'); Cnode:=Unode; Inode:=CNode.ChildNodes.FindNode('Condition'); while unode<>nil do begin QNode:=inode.ChildNodes.FindNode('questions'); if qnode=nil then begin memo1.lines.add('=== No questions for Illness === '); end; if qnode<>nil then begin qNode:=qNode.ChildNodes.FindNode('Question'); memo1.Lines.add('==== New Questions ===='); while qnode<>nil do begin quest:=qnode.ChildNodes['Text'].text; memo1.Lines.add(quest); answer:=qnode.ChildNodes['currentAnswer'].ChildNodes['Text'].text; memo1.lines.add(answer); qNode:=qnode.NextSibling; end; end; lnode:=unode; unode:=unode.NextSibling; if unode=nil then begin unode:=lnode; inode:=inode.NextSibling; if inode=nil then unode:=nil; end else begin CNode:=Unode.ChildNodes.FindNode('conditions'); Inode:=CNode.ChildNodes.FindNode('Condition'); end; end; end; hnode:=hnode.nextsibling; end; ANode := ANode.NextSibling; until ANode = nil; end else memo1.lines.Add('No Illness or Questions Found '); memo1.Lines.SaveToFile(who); showmessage('done'); 
0
source

Source: https://habr.com/ru/post/1392925/


All Articles