2014-11-03 27 views
1

我需要轉換所有字符|在所有文本中標記大XML文件的塊。也就是說,只要我發現如何使用Closure XML將元素注入字符內容?

<test att="one|two">content | something more | and done</test> 

我需要轉換到

<test att="one|two">content <bar/> something more <bar/> and done</test> 

注意|也可能出現在屬性值中,並且在這種情況下,它們必須保持不變。閱讀CXML focumentation的SAX概述部分的Transforming幻燈片後,我寫了

(defclass preproc (cxml:sax-proxy)()) 

(defmethod sax:characters ((handler preproc) data) 
    (call-next-method handler (cl-ppcre:regex-replace "\\|" data "<bar/>"))) 

但當然,它產生一個字符串(逃脫)沒有在最後的XML標籤。

WML> (cxml:parse "<test>content | ola</test>" 
        (make-instance 'preproc 
            :chained-handler (cxml:make-string-sink))) 
<?xml version="1.0" encoding="UTF-8"?> 
<test>content &lt;bar/&gt; ola</test>" 

任何想法或方向?

+0

這個問題並非是對 「商業可擴展標記語言」,所以我除去[標籤:CXML]標籤。 – 2014-11-03 15:59:20

+0

cxml是不是「商業可擴展標記語言」的CL包的名稱。 – 2014-11-04 14:43:13

+0

是的,我對包裝很熟悉;它是我的[CL-RDFXML](https://github.com/tayloj/cl-rdfxml)解析器的依賴項。但是,Stack Overflow上的[tag:cxml]標記根據其標記wiki,用於「商業可擴展標記語言」。如果將鼠標光標懸停在標籤上,則會顯示說明。 (順便說一句,我發現這很多與[tag:owl]和[tag:owl-carousel]標籤有關。) – 2014-11-04 14:45:52

回答

2

處理程序不調用解析器,但是處理已解析的值。因此,而不是構建字符串包含<酒吧/ >,你想要做的是調用,將是否實際上已經遇到<酒吧/ >已調用的方法。在這種情況下,如果該文件實際上已經有

content <bar/> ola 

測試元素內,那麼就不會有來電:

(sax:characters handler "content ") 
(sax:start-element handler nil nil "bar" '()) 
(sax:end-element handler nil nil "bar" 
(sax:characters handler " ola") 

所以,你需要做的是分割字符串在|字符(如果需要,可以使用CL-PPCRE,雖然可能有更輕量級的解決方案),然後對每個字符串部分執行調用next-method,並調用sax:start-element薩克斯:最終元件在之間:

(defmethod sax:characters ((handler preproc) data) 
    (let ((parts (cl-ppcre:split "\\|" data))) 
    ;; check this on edge cases, though, e.g., "", "|", "a|", strings 
    ;; without any "|", etc. 
    (call-next-method handler (pop parts)) 
    (dolist (part parts) 
     (sax:start-element handler nil nil "bar" '()) 
     (sax:end-element handler nil nil "bar") 
     (call-next-method handler part)))) 

(cxml:parse "<test>content | ola</test>" 
      (make-instance 'preproc 
          :chained-handler (cxml:make-string-sink))) 
;=> 
; "<?xml version=\"1.0\" encoding=\"UTF-8\"?> 
; <test>content <bar/> ola</test>" 
+0

這個答案几乎是我從昨天在Cxml-devel列表中收到的來自Russ Tyndall的那個(http://mailman.common-lisp.net/pipermail/cxml-devel/2014-November/000009.html)! – 2014-11-04 14:49:07

+0

@AlexandreRademaker那麼,這可能是一個好兆頭,那麼! – 2014-11-04 14:50:07

+0

關於「處理程序不調用解析器,但正在處理已解析的值...」。我不明白這個評論。當然,處理程序不會調用解析器,我從來沒有懷疑過相反的情況。這裏對我來說最新的是我們可以調用sax:start-element或者sax:end-element方法(即fire事件),而不僅僅是響應它們。 – 2014-11-04 14:53:09

相關問題