I have Object class like that:
:Class People
:Field Public Type ← 'contact'
:Field Public Name ← ⍬
:Field Public Company ← ⍬
:Field Public Position ← ⍬
:Field Public Fax ← ⍬
:Field Public Email ← ⍬
∇ make args
:Access Public
:Implements Constructor
Name ← args[1]
Company ← args[2]
Position ← args[3]
⎕ ← 'New people maked'
∇
:EndClass
And I have an array of Objects of People class
Peoples ← (⎕New People ('Name1' 'Company1' 'Founder')) (⎕New People ('Name2' 'Company2' 'Founder'))
New people maked
New people maked
Peoples
#.[People] #.[People]
How do I export Peoples to an xml file? And then import an array from xml?
The task is to save the array and load it from the file when you restart it.
Look into the system function ⎕XML
and decide on a way to represent your fields as XML.
You may bump into a problem with your field values being nested scalars. This is because you use args[1]
etc. instead of 1⊃args
etc. or simply (Name Company Position)←args
.
With the nesting problem resolved, we can add a method to generate part of the matrix that ⎕XML
needs. I've decided on a simple schema here, but you can make it whatever you want:
:Class People
:Field Public Type ← 'contact'
:Field Public Name ← ⍬
:Field Public Company ← ⍬
:Field Public Position ← ⍬
:Field Public Fax ← ⍬
:Field Public Email ← ⍬
∇ make args
:Access Public
:Implements Constructor
(Name Company Position)←args
⎕←'New people maked'
∇
∇ nvm←XmlMat
:Access public
nvm←1 'People' ''⍪↑{2 ⍵(⍕⍎⍵)}¨⎕NL ¯2
∇
:EndClass
Peoples.XmlMat
┌─────────────────────┬─────────────────────┐
│┌─┬────────┬────────┐│┌─┬────────┬────────┐│
││1│People │ │││1│People │ ││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Company │Company1│││2│Company │Company2││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Email │ │││2│Email │ ││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Fax │ │││2│Fax │ ││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Name │Name1 │││2│Name │Name2 ││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Position│Founder │││2│Position│Founder ││
│├─┼────────┼────────┤│├─┼────────┼────────┤│
││2│Type │contact │││2│Type │contact ││
│└─┴────────┴────────┘│└─┴────────┴────────┘│
└─────────────────────┴─────────────────────┘
Here's then a function that takes a vector of People
s and constructs the final argument to supply ⎕XML
:
ToXML←{⎕XML 0 'Peoples' ''⍪⊃⍪⌿⍵.XmlMat}
ToXML Peoples
<Peoples>
<People>
<Company>Company1</Company>
<Email></Email>
<Fax></Fax>
<Name>Name1</Name>
<Position>Founder</Position>
<Type>contact</Type>
</People>
<People>
<Company>Company2</Company>
<Email></Email>
<Fax></Fax>
<Name>Name2</Name>
<Position>Founder</Position>
<Type>contact</Type>
</People>
</Peoples>
Writing the XML to a file is a simple as:
'peoples.xml'⎕NPUT⍨ToXML Peoples
Next, we want to load the XML and create People
objects from it. Getting the XML content into matrix form is easy (output abbreviated for brevity):
⎕XML⊃⎕NGET'peoples.xml'
┌─┬────────┬────────┬───┬─┐
│0│Peoples │ │ │3│
├─┼────────┼────────┼───┼─┤
│1│People │ │ │3│
├─┼────────┼────────┼───┼─┤
│2│Company │Company1│ │5│
├─┼────────┼────────┼───┼─┤
: : : : : :
We're only interested in the first three columns, which are XML nesting level, name, and value:
(level name value)←↓3↑⍉⎕XML⊃⎕NGET'peoples.xml'
We can now partition the names and values that belong together:
name⊆⍨2=level
┌──────────────────────────────────────┬──────────────────────────────────────┐
│┌───────┬─────┬───┬────┬────────┬────┐│┌───────┬─────┬───┬────┬────────┬────┐│
││Company│Email│Fax│Name│Position│Type│││Company│Email│Fax│Name│Position│Type││
│└───────┴─────┴───┴────┴────────┴────┘│└───────┴─────┴───┴────┴────────┴────┘│
└──────────────────────────────────────┴──────────────────────────────────────┘
value⊆⍨2=level
┌──────────────────────────────────┬──────────────────────────────────┐
│┌────────┬┬┬─────┬───────┬───────┐│┌────────┬┬┬─────┬───────┬───────┐│
││Company1│││Name1│Founder│contact│││Company2│││Name2│Founder│contact││
│└────────┴┴┴─────┴───────┴───────┘│└────────┴┴┴─────┴───────┴───────┘│
└──────────────────────────────────┴──────────────────────────────────┘
Let's amend the class with a niladic constructor so we can set the field values after construction:
:Class People
:Field Public Type ← 'contact'
:Field Public Name ← ⍬
:Field Public Company ← ⍬
:Field Public Position ← ⍬
:Field Public Fax ← ⍬
:Field Public Email ← ⍬
∇ make0
:Access Public
:Implements Constructor
⎕←'New people maked'
∇
∇ make args
:Access Public
:Implements Constructor
(Name Company Position)←args
⎕←'New people maked'
∇
∇ nvm←XmlMat
:Access public
nvm←1 'People' ''⍪↑{2 ⍵(⍕⍎⍵)}¨⎕NL ¯2
∇
:EndClass
And finally, we can create our FromXML
function based on the above experiments:
FromXML←{
(level name value)←↓3↑⍉⎕XML ⍵
(names values)←name value⊆¨⍨⊂2=level
names{p⊣(p←⎕NEW People)⍎(∊' ',¨⍺),'←⍵'}¨values
}
FromXML⊃⎕NGET'peoples.xml'
New people maked
New people maked
#.[People] #.[People]