开发者

Using the member function in Scheme

This is my code:

   (define p (read(open-input-file "starbucks4.sxml")))

(define get-artifacts
  (lambda (l)
   (member (list 'opm:artifact) l)))



  (get-artifacts p)

I was told that the member function searches completely throughout a list. I开发者_运维问答n the .sxml document there is a complicated list that has many elements called "opm:artifact" however this method returns #f and no list.

Can anyone see what I am doing wrong?

Sample of .sxml file:

      (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "Provide other Beverage")))
   "\n        ")
  "\n    ")
 "\n    "
 (opm:artifacts
  ()
  "\n        "
  (opm:artifact
   ((id "a1"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "order")))
   "\n        ")
  "\n        "
  (opm:artifact
   ((id "a2"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "cash")))
   "\n        ")
  "\n        "

I'm trying to look for all the opm:artifacts and the associated data (it's sublists).


It does search through the whole list, but it doesn't search sublists.

So if your list is actually a nested list and the (opm:artifact) is only in one of its sublists, member won't find it.

Also note that you're looking for the list (opm:artifact), not the symbol opm:artifact or any list containing opm:artifact.

Edit: To search sublists you can do something like this:

(define (deep-search x lst)
  (if (empty? lst)
    #f
    (if (equal? x (car lst))
      #t
      (begin
        (if (list? (car lst))
          (let ((r (deep-search x (car lst))))
               (if r
                 r
                 (deep-search x (cdr lst))))
          (deep-search x (cdr lst)))))))


The first thing I noticed is that you are giving a list of one element as your first argument to member. Member works like this:

>>> (member 2 '(4 5 2 6 7))
(2 6 7)

Can you give us a sample of what p looks like, and what you want as a result?


Hang on, I can make your life a whole bunch easier. Based on your "starbucks.sxml" file name, it looks like you're already using the sxml racket package. If so, then you can also use the 'sxpath' part of that library to simplify your code drastically:

#lang racket

(require (planet lizorkin/sxml:2:1/sxpath))

(define tree (file->value "/tmp/starbucks.sxml"))

(define artifact-filter (sxpath '(opm:artifact)))

(artifact-filter tree)

This returns a list of the opm:artifact nodes (including everything inside them). For instance, when I ran it on the fragment you provide above (plus a bunch of inserted open-parens--they weren't balanced--I got this:

Welcome to DrRacket, version 5.0.2.1--2010-10-27(41c084c/g) [3m].
Language: racket; memory limit: 512 MB.
'((opm:artifact
   ((id "a1"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "order")))
   "\n        ")
  (opm:artifact
   ((id "a2"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "cash")))
   "\n        "))

The documentation for the whole sxml package is really bad... perhaps "nonexistent" would be a better word; to be fair, though, the sxml folks are interested in supporting all Schemes, not just Racket, so they can certainly be forgiven for not spending lots of time writing documentation in the Racket format, Scribble.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜