代码之家  ›  专栏  ›  技术社区  ›  toolkit

clojure命名空间感知xml解析器/zipper

  •  3
  • toolkit  · 技术社区  · 12 年前

    有人知道有名称空间感知的xml解析器/zipper吗?

    我不需要引入一大堆axis或类似的libs,而是希望解析以下内容:

    (ns foo
      (:require [clojure.zip :as zip]
                [clojure.xml :as xml])
      (:use clojure.data.zip.xml))
    
    (def xml "<soap:Envelope xmlns=\"urn:WEBSERVICE-URN\"
                             xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"
                             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
                <soap:Body>
                  <loginResponse>
                     <result>           
                        <sessionKey>SESSION-KEY-HERE</sessionKey>
                     </result>
                  </loginResponse>
                </soap:Body>
               </soap:Envelope>")
    
    (def root 
      (zip/xml-zip 
        (xml/parse 
          (java.io.ByteArrayInputStream. (.getBytes xml "UTF-8")))))
    
    (def key (xml1-> root ???? ???? :loginResponse :result :sessionKey text))
    

    我似乎无法导航具有xml名称空间的xml元素?

    1 回复  |  直到 12 年前
        1
  •  5
  •   Alex    12 年前

    我认为你的问题可能是你使用了 xml1-> 而不是XML中的名称空间。这个 tag= XML zip命名空间中的谓词(当使用关键字 xml1-> )默认为自动下降模式,这意味着在尝试匹配元素标记之前,它会下降到当前节点的子节点。由于根元素已经是 soap:Envelope ,您不需要将该筛选器包含在列表中 xml1-> 。以下内容应该会为您提供所需信息:

    (xml1-> root :soap:Body :loginResponse :result :sessionKey text)
    

    请注意,元素qname以未展开的形式用作中的标记名 clojure.xml ,并且有一个名称包含冒号的关键字是完全可以的。

    或者,您可以说:

    (require '[clojure.data.zip :as zf])
    (xml1-> (zf/auto false root)
            :soap:Envelope :soap:Body :loginResponse :result :sessionKey text)
    

    如果您仍然需要一个支持名称空间的XML解析器 data.xml ,尽管它只是简单地丢弃名称空间声明并仅使用本地名称:

    (require '[clojure.data.xml :as data-xml])
    (def root (-> (java.io.StringReader. xml) data-xml/parse zip/xml-zip)
    (xml1-> root :Body :loginResponse :result :sessionKey text)