2010-10-26 2 views
2

Это мой код:Использование функции члена в схеме

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

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



    (get-artifacts p) 

мне сказали, что функция член полностью выполняет поиск по всему списку. В документе .sxml есть сложный список, который содержит много элементов, называемых «opm: artifact», но этот метод возвращает #f и нет списка.

Может ли кто-нибудь увидеть, что я делаю неправильно?

Пример .sxml файла:

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

Я пытаюсь искать все OPM: артефакты и связанные с ними данные (это подсписки).

ответ

2

Он выполняет поиск по всему списку, но не выполняет поиск подписок.

Так что, если ваш список на самом деле является вложенным списком, а (opm:artifact) находится только в одном из его подписок, member не найдет его.

Также обратите внимание, что вы ищете список (opm:artifact), а не символ opm:artifact или любой список, содержащий opm:artifact.

Edit: Для поиска подсписки вы можете сделать что-то вроде этого:

(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))))))) 
+0

Спасибо, что бы найти символ opm: artefact? – Alex

+1

@Alex: '(deep-search 'opm-artifact p)' Обратите внимание, что это вернет true или false. Вам нужно немного изменить его, если вам нужно больше. – sepp2k

+1

@Alex: Также обратите внимание, что в файле примера вы показали, что 'p' будет содержать только' (opm: account ((ref "detailAccount"))) ', так как' read' только читает одну форму. – sepp2k

0

Первое, что я заметил, что вы даете список одного элемента в качестве первого аргумента member. Участник работает следующим образом:

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

Можете ли вы дать нам пример того, что p выглядит, и то, что вы хотите в итоге?

+1

Спасибо! Я редактировал свой оригинальный вопрос с помощью некоторого примера p. – Alex

0

Держитесь, я могу сделать вашу жизнь целым сгустком легче. Основываясь на имени файла «starbucks.sxml», похоже, что вы уже используете пакет sxml racket. Если да, то вы также можете использовать «» SXPath часть этой библиотеки, чтобы упростить код резко:

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

Это возвращает список из OPM: артефакт узлов (включая все внутри них). Например, когда я запустил его на фрагменте указанного выше (плюс кучу вставленных ОТКРЫТОГО скобка - они не были сбалансированы - Я получил это:

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

Документации для всего пакета SXPath, является действительно плохо ... возможно, «несуществующий» был бы лучшим словом, но, честно говоря, люди sxml заинтересованы в поддержке всех схем, а не только Racket, поэтому их можно, конечно же, простить за то, что они не тратят много времени на разработку документации в формат Racket, Scribble.