【问题标题】:How to parse XML with cxml and stp containing ampersand如何使用包含 & 符号的 cxml 和 stp 解析 XML
【发布时间】:2012-10-01 17:31:14
【问题描述】:

我想解析以下 XML-Code:

(cxml:parse "<BEGIN><URL>www.some.de/url?some=data&bad=stuff</URL></BEGIN>" (stp:make-builder))

这会导致

 #<CXML:WELL-FORMEDNESS-VIOLATION "~A" {1003C5E163}>

因为 '&' 是一个 XML 特殊字符。但如果我改用&amp;amp;?,结果是:

(cxml:parse "<BEGIN><URL>www.some.de/url?some=data&amp;bad=stuff</URL></BEGIN>" (stp:make-builder))
=>#.(CXML-STP-IMPL::DOCUMENT
   :CHILDREN '(#.(CXML-STP:ELEMENT
                  #| :PARENT of type DOCUMENT |#
                  :CHILDREN '(#.(CXML-STP:ELEMENT
                                 #| :PARENT of type ELEMENT |#
                                 :CHILDREN '(#.(CXML-STP:TEXT
                                                #| :PARENT of type ELEMENT |#
                                                :DATA "www.some.de/url?some=data")
                                             #.(CXML-STP:TEXT
                                                #| :PARENT of type ELEMENT |#
                                                :DATA "&")
                                             #.(CXML-STP:TEXT
                                                #| :PARENT of type ELEMENT |#
                                                :DATA "bad=stuff"))
                                 :LOCAL-NAME "URL"))
                  :LOCAL-NAME "BEGIN")))

这与我的预期不完全一样,因为应该只有一个 CXML-STP:TEXT 子节点的 DATA "www.some.de/url?some=data&bad=stuff"

我该如何解决这个错误(?)行为?

【问题讨论】:

    标签: common-lisp stp


    【解决方案1】:

    这种行为虽然不是很方便,但实际上也存在于许多其他 XML 解析器中。可能它的原因是能够解析任意 XML 实体并将一些用户定义的规则应用于它们。虽然,它可能只是解析器实现的副产品。我还没有找到。

    对于解析器的 SAX 变体,我采用了以下方法:

    (defclass my-sax (sax:sax-parser-mixin)
      ((title :accessor title :initform nil)
       (tag :accessor tag :initform nil)
       (text :accessor text :initform "")))
    
    (defmethod sax:start-element ((sax my-sax) namespace-uri local-name
                                  qname attributes)
      (with-slots (tag tagcount text) sax
                  (setf tag local-name
                        text "")))
    
    (defmethod sax:characters ((sax my-sax) data)
      (with-slots (title tag text) sax
        (switch (tag :test 'string=)
          ("text"  (setf text (conatenate 'string text data)))
          ("title" (setf title data)))))
    
    (defmethod sax:end-element ((sax my-sax) namespace-uri local-name qname)
      (with-slots (title tag text) sax
        (when (string= "text" local-name)
          ;; process (text sax)
        )))
    

    即我在sax:characters 中收集文本并在sax:end-element 中处理它。在 STP 中,您可能只需连接相邻的 text 元素就可以更轻松地摆脱困境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多