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

From: Stephen De Gabrielle (stephen at degabrielle.name)
Date: Wed Jan 2 19:40:17 EST 2008

Thanks guys,
you've got me on the right path.

Get well soon,

Stephen

 I must get to bed (12.40am)



On Jan 3, 2008 12:30 AM, Matt Jadud <jadudm at gmail.com> wrote:
> A brute-force approach with match would look roughly like the code
> below; note that I have the flu right now, and also have no idea where
> some of your resulting data comes from (it appears by magic in your
> alist example).
>
> Cheers,
> Matt
>
> (define data
>   '(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")))
>      )
>     ))
>
> (require (lib "plt-match.ss")
>          (lib "list.ss"))
>
> (define-struct edge (source target))
> (define-struct node (id name gender))
>
> (define (parse s)
>   (match s
>     [`(graphml ,_ ,graph)
>       (parse graph)]
>     [`(graph ,_ ,elements ...) ;; I used the ,_ to say "something is
> here, but I don't care what it is"
>      (filter (lambda (s)
>                (or (edge? s) (node? s))) (map parse elements))]
>     [`(key ,_ ...) (void)] ;; I don't know what to do with (key ...) elements.
>     [`(node ((id ,id)) (data ((key "name")) ,name) (data ((key "gender")) ,g))
>      (make-node id name g)]
>     [`(edge ((source ,s) (target ,t)))
>      (make-edge s t)]))
>
> You may be able to use xquery or some other libraries to do this in
> more elegant ways; this is a brute-force approach that might get you
> close.
>
> Cheers,
> Matt
>
>
> On Jan 2, 2008 7:02 PM, Robby Findler <robby at cs.uchicago.edu> wrote:
> > Oh, I see. Yes, match is probably the right thing (using the
> > quasiquote patterns). There may be a planet library for doing what you
> > want more directly, I don't know. But assuming not, match.ss.
> >
> > Robby
> >
> >
> > On Jan 2, 2008 5:55 PM, Stephen De Gabrielle <stephen at degabrielle.name> wrote:
> > > 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
> > >
> > _________________________________________________
> >   For list-related administrative tasks:
> >   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> >
>



-- 
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


Posted on the users mailing list.