2014-11-03 71 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

相关问题