[plt-scheme] getting data out of xexpr's (xml)

From: Stephen De Gabrielle (stephen at degabrielle.name)
Date: Wed Jan 2 18:55:32 EST 2008

Thanks for the quick response;

My trouble isn't geting the xml into xexper, but turning xexpr into
key/value pairs.

I do this;

                                                      (xml->xexpr

((eliminate-whitespace '(graphml graph node edge) (lambda (x) x))

(document-element (read-xml input-port))))

Which gets much the same output as this

(require (lib "xml.ss" "xml"))
(xml->xexpr (read-xml/element (open-input-string "
<graphml xmlns='http://graphml.graphdrawing.org/xmlns'>
<!-- metadata -->
<graph edgedefault='undirected'>

<key id='name' for='node' attr.name='name' attr.type='string'/>
<key id='gender' for='node' attr.name='gender' attr.type='string'/>

<!-- data -->
<node id='1'>
 <data key='name'>Jeff</data>
 <data key='gender'>M</data>
 </node>
<node id='2'>
 <data key='name'>Ed</data>
 <data key='gender'>M</data>
</node>
<node id='3'>
 <data key='name'>Christiaan</data>
 <data key='gender'>M</data>
</node>

<edge source='2' target='1'></edge>
<edge source='3' target='3'></edge>
<edge source='1' target='2'></edge>

</graph>
</graphml>")))

which gives approximately;

(graphml
  ((xmlns "http://graphml.graphdrawing.org/xmlns"))
  (graph
   ((edgedefault "undirected"))
   (key ((attr.name "name") (attr.type "string") (for "node") (id "name")))
   (key ((attr.name "gender") (attr.type "string") (for "node") (id "gender")))
   (node ((id "1"))  (data ((key "name")) "Jeff")  (data ((key "gender")) "M") )
   (node ((id "2"))  (data ((key "name")) "Ed")  (data ((key "gender")) "M") )
   (node ((id "3"))  (data ((key "name")) "Christiaan")  (data ((key
"gender")) "M") )
   (edge ((source "21") (target "126")))
   (edge ((source "21") (target "127")))
   (edge ((source "21") (target "128")))
   (edge ((source "21") (target "129")))
   )
  )


I'd like to use something like a regular expression, perhaps?
  /(node ((id $1))  (data ((key $2)) $3)/((class node) (id $1) ($2 $3) ($4 $5))/

to get  a series of alists [1];

((class "graph-metadata") (dir #f))
((class "node") (id "1") ("name" "Jeff")  ("gender" "M"))
((class "node") (id "2") ("name" "Ed")  ("gender" "M"))
((class "node") (id "3") ("name" "Christiaan") ("gender" "M"))
((class "edge") (source "21") (target "126") (dir #f))
((class "edge") (source "21") (target "127") (dir #f))
((class "edge") (source "21") (target "128") (dir #f))
((class "edge") (source "21") (target "129") (dir #f))

Does this make more sense? It's turning the xexpr into key/value pairs
without making a labrinthine mess of for-each/map and caddr etc. like
in my original code that I need to work out. match.ss seems to be
about macros, so I'm not sure I'm on the right path.

Thanks,

Stephen


[1]Which I will process to add derived fields to ;
eg  ((class "node") (id "1") ("name" "Jeff")  ("gender" "M")  (x-pos
43) (y-pos 34) (colour "Blue"))
(then finally turn into snips)




On Jan 2, 2008 10:54 PM, Robby Findler <robby at cs.uchicago.edu> wrote:
> I think you want:
>
> (require (lib "xml.ss" "xml"))
> (xml->xexpr (read-xml/element (open-input-string "<a><b>cdef</b></a>")))
>
> which produces
>
> '(a () (b () "cdef"))
>
> hth,
> Robby
>
>
> On Jan 2, 2008 4:51 PM, Stephen De Gabrielle <stephen at degabrielle.name> wrote:
> > Hi,
> >
> > I'm using  (lib "xml.ss" "xml") to read some GraphML  into xexpr's
> >
> >
> > Once I have loaded it I'm using this sort of (non-working)thing  to
> > turn it from the xexpr into an alist using for-each and
> > caddr/cadr/car/cdr etc.
> >
> > ;; populate ;;
> >       (let* ((data (cdr (caddr xexpr-graph)))) ; get the graph part
> >         (for-each
> >          (lambda (row) ;; badly named local for node or edge tag.
> >            (if (equal? '(edgedefault "undirected") row) (set! edge-directed #t)
> >                (let* ((row-type (car row))
> >                       (row-Attributes (if (or (equal? row-type 'node)
> >                                                (equal? row-type
> > 'edge)) (get-row-Attributes row))))
> >                  (send alist-collection insert (append (list (list
> > 'class row-type)) (car row-Attributes) (cadr row-Attributes )))))) ;;
> > add an alist to the collection for each node or edge
> >          data))
> >
> >  (http://graphml.graphdrawing.org/ socialnet.xml example attached)
> >
> > My Question is - is there a better way of getting my nodes, edges and
> > [graph] metadata(directed/undirected) as what I am writing here is
> > hard to write, hard to read, and doesn't even work.
> >
> > Should I use  plt-match.ss or  match.ss instead?
> >
> > Can anyone suggest some code in 'PLT-Full' (v3.99.0.8) that I can
> > read. It doesn't have to be xml - just xexpr-like - and I am getting
> > getter at reading code, even without comments :)
> >
> >
> > Cheers,
> >
> > Stephen
> >
> >
> >
> > --
> > Stephen De Gabrielle
> > s.degabrielle at ucl.ac.uk
> > Telephone +44 (0)20 7679 5242 (x45242)
> > Mobile                  079 851 890 45
> > http://www.uclic.ucl.ac.uk/annb/MaSI.html
> > University College London Interaction Centre
> > Remax House - 31/32 Alfred Place
> > London - WC1E 7DP
> >
> > "There's an old story about the person who wished his computer were as
> > easy to use as his telephone.  That wish has come true, since I no
> > longer know how to use my telephone. " -- Bjarne Stroustrup
> >
> > _________________________________________________
> >   For list-related administrative tasks:
> >   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> >
> >
>



-- 




--
Stephen De Gabrielle
s.degabrielle at ucl.ac.uk
Telephone +44 (0)20 7679 5242 (x45242)
Mobile                  079 851 890 45
http://www.uclic.ucl.ac.uk/annb/MaSI.html
University College London Interaction Centre
Remax House - 31/32 Alfred Place
London - WC1E 7DP

"There's an old story about the person who wished his computer were as
easy to use as his telephone.  That wish has come true, since I no
longer know how to use my telephone. " -- Bjarne Stroustrup


Posted on the users mailing list.