[英]How to match any element?
这很好用:
(sxml-match '(div)
((div) #t))
但这失败了:
(sxml-match '(div)
((,element) #t))
我想知道如何匹配任何元素?
这是一个更具体的例子。 以下是 XCB 的“ xproto.xml ”文件的片段:
(define xproto '((struct (@ (name "CHAR2B"))
(field (@ (type "CARD8") (name "byte1")))
(field (@ (type "CARD8") (name "byte2"))))
(xidtype (@ (name "WINDOW")))
(xidtype (@ (name "PIXMAP")))
(xidtype (@ (name "ATOM")))
(xidunion (@ (name "DRAWABLE"))
(type "WINDOW")
(type "PIXMAP"))))
我的目标是提取名称:
(define names '((struct "CHAR2B")
(xidtype "WINDOW")
(xidtype "PIXMAP")
(xidtype "ATOM")
(xidunion "DRAWABLE")))
所以我尝试了这个:
(sxml-match xproto ((,kind (@ (name ,name)) . ,body) ...))
但我得到错误:
错误的模式语法(不是元素模式)
我不明白我还应该做什么。
sxml-match
是否不足以胜任这项工作?
从它遵循的Backus-Naur 形式来看,做(,div)
在句法上是不正确的。 这仅匹配element-pattern
左侧符号,并正在等待car
位置中的tag-symbol
。 但这样做是正确的(sxml-match '(div) (,element 10))
,因为这与节点的pat-var-or-cata
规则匹配。 所以做(,something) then
是语法错误,因为,something
只匹配pat-var-or-cata
规则。
这些规则看起来非常类似于通过某种统一而产生的预设语法。
更新您的示例:
我在CAR位置的前2层嵌套分别加了一个常量@
,不然不知ww
不行。
(define xproto '(@
(ww struct (@ (name "CHAR2B"))
(field (@ (type "CARD8") (name "byte1")))
(field (@ (type "CARD8") (name "byte2"))))
(ww xidtype (@ (name "WINDOW")))
(ww xidtype (@ (name "PIXMAP")))
(ww xidtype (@ (name "ATOM")))
(ww xidunion (@ (name "DRAWABLE"))
(type "WINDOW")
(type "PIXMAP"))))
(sxml-match xproto
((@ (ww ,t . ,d) ...) (list "???" t))
(,otherwise "no match"))
(sxml-match xproto
((@ (ww (@ (name ,t)) . ,d) ...) (list "???" t))
(,otherwise "no match"))
您可以压缩这 2 个表达式的结果来获取它。
您必须包含特定的元素和属性名称才能匹配并从中提取信息; 它们必须是硬编码的并且不能是可变的。 但是因为您知道 DTD 以及文档的结构,所以您知道需要匹配什么。 这很乏味。 命名的变形可以帮助保持事物结构化:
(define (get-names xproto)
; match a single struct/xidtype/xidunion element and return
; which element and its name attribute
(define (struct/xid x)
(sxml-match x
((struct (@ (name ,name)) . ,rest) (list 'struct name))
((xidtype (@ (name ,name))) (list 'xidtype name))
((xidunion (@ (name ,name)) . ,rest) (list 'xidunion name))))
; Match a nodeset of 0 or more struct/xidtype/xidunion elements
(sxml-match xproto
((list ,(struct/xid -> element+name) ...)
`(,element+name ...))))
为您的示例数据返回((struct "CHAR2B") (xidtype "WINDOW") (xidtype "PIXMAP") (xidtype "ATOM") (xidunion "DRAWABLE"))
。
文档说 catamorphism 函数可以返回可以绑定到多个 id 的多个值,但我这样做的尝试不断引发错误(多个值/id 和...
似乎不能一起玩),所以这只是返回列出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.