how to remove all attribute-list in diference level of SXML?

Started by psilwen, July 02, 2014, 10:39:52 PM

Previous topic - Next topic

psilwen

when a xml document has been converted to SXML, and how to remove all attribute-list of it? these attribute-lists inside diference level of SXML.
(reverse \"newlisp\")

psilwen

I waited three days, no one answered me. This forum is too deserted.



okay, another question:



(set 'data '((apples 123) (bananas 123 45) (bananas 123 678) (pears 7)))
(assoc 'bananas data)


gets


(bananas 123 45)

how to 'assoc' the second 'bananas' list?



the question is, like this

(  (li "listitem 1")
   (li "listitem 2")
   (p "some text")
   (li "listitem 3")
   (p "some text")
   (li "listitem 4")  )


how to 'assoc' the nth 'li'?



is there a function can gets a collection of 'li' list?



anybody know? please help me. thanks
(reverse \"newlisp\")

ryuo

I don't know if this is what you wanted, but I was able to dig up a way to get access to all the occurences of 'bananas' in the list.



(set 'data '((apples 123) (bananas 123 45) (bananas 123 678) (pears 7)))

(setf (data (((ref-all 'bananas data) 1) 0)) '(bananas 0 0))

(println data)

(exit)


ref-all finds all the elements that are lists beginning with bananas, and returns a list of the indexes. I tell it to take the second occurrence of this bananas list and take the 1st index from that list and use that index to retrieve a reference to the desired element from the data list. setf then overwrites the old value of that element with a new list. println confirms that it has changed.



Anyway, I hope this was helpful.

rrq

Another, maybe simpler, way is:
(find-all '(bananas *) data)

psilwen

Quote(find-all '(bananas *) data)


Very well!



This is exactly what I want! I didn't expect so simple.



Thanks for ryuo and ralph.ronnquist .



But how about to remove all attribute-list in different level of SXML?



This is more difficult, right?



What better way to do.
(reverse \"newlisp\")

rickyboy

Quote from: "psilwen"But how about to remove all attribute-list in different level of SXML?



This is more difficult, right?



What better way to do.

Before I start, a fair warning: sometimes my solutions are "more work" than the interpreter needs to  do because I've failed to use a primitive that could have done the same thing. :)  But barring that, here's an idea.



I assume you want to clean (i.e. filter out) the attribute lists from your sxml.  In doing so, you might use a predicate like this, with the primitive clean, to identify the attribute lists.


(define (is-attr-list? THING)
  (and (list? THING)
       (= '@ (first THING))))

However the clean primitive is "too shallow" for the job, e.g.


> [cmd]
(clean is-attr-list?
    '("dl"
      (@ ("class" "codebox"))
      ("dt" "Code: " ("a" (@ ("href" "#") ("onclick" "selectCode(this); return false;"))
        "Select all"))
      ("dd" ("code" "(find-all '(bananas *) data)"))))
[/cmd]
("dl" ("dt" "Code: " ("a" (@ ("href" "#") ("onclick" "selectCode(this); return false;"))
   "Select all"))
 ("dd" ("code" "(find-all '(bananas *) data)")))
>


It removes only the attribute list at the top level.



What is needed is something like a "deepening" form of clean.  I had tried doing something with the replace primitive, but didn't have any luck; so I resorted to writing this new function instead.


(define (deep-clean PREDICATE LIST)
  (if (not (list? LIST))
      LIST
      (map (curry deep-clean PREDICATE)
           (clean PREDICATE LIST))))

Now, you can get rid of all the attribute lists from your sxml.


> [cmd]
(deep-clean is-attr-list?
    '("dl"
      (@ ("class" "codebox"))
      ("dt" "Code: " ("a" (@ ("href" "#") ("onclick" "selectCode(this); return false;"))
        "Select all"))
      ("dd" ("code" "(find-all '(bananas *) data)"))))
[/cmd]
("dl" ("dt" "Code: " ("a" "Select all")) ("dd" ("code" "(find-all '(bananas *) data)")))
>

I hope that helps.  Sorry for the long comment.
(λx. x x) (λx. x x)

rrq

rickyboy's "deep-clean" is quite good.



As a minimalist, I'd gone for a slightly more specialized solution; for example, if the SXML is regular, and in particular includes the attribute sub list for every node, i.e., even the empty ones, then I'd choose to simply traverse it, and remove the second of every sub list, with:
(define (drop-attrs sxml)
  (if (list? sxml) (cons (sxml 0) (map drop-attrs (2 sxml))) sxml))


If the SXML is not regular, but rather include the '@ marker for the attribute sub list when present, I'd expand it slightly:
(define (drop-attrs sxml)
  (if (list? sxml)
     (cons (sxml 0)
           (map drop-attrs
                ((if (and (1 sxml) (= '@ ((sxml 1) 0))) 2 1) sxml)))
     sxml))

or maybe, I'd then use "deep-clean" even though it applies the attribute test a bit more widely than strictly warranted.

psilwen

Quote from: "rickyboy"

(define (is-attr-list? THING)
  (and (list? THING)
       (= '@ (first THING))))


(define (deep-clean PREDICATE LIST)
  (if (not (list? LIST))
      LIST
      (map (curry deep-clean PREDICATE)
           (clean PREDICATE LIST))))


> [cmd]
(deep-clean is-attr-list?
    '("dl"
      (@ ("class" "codebox"))
      ("dt" "Code: " ("a" (@ ("href" "#") ("onclick" "selectCode(this); return false;"))
        "Select all"))
      ("dd" ("code" "(find-all '(bananas *) data)"))))
[/cmd]
("dl" ("dt" "Code: " ("a" "Select all")) ("dd" ("code" "(find-all '(bananas *) data)")))
>




to rickyboy:



Thank you very much for your reply.



I tried it. It works perfect.



Also once again thanks to ralph.ronnquist for your enthusiastic.
(reverse \"newlisp\")

rickyboy

psilwen: You're very welcome. Glad we could help. Also, I love your login name. :)



ralph.ronnquist: Very nice stylistic points. I'm enjoying your other posts too.  Keep 'em coming!
(λx. x x) (λx. x x)