3

有谁知道命名空间感知 xml 解析器/拉链?

我希望解析以下内容,而不是引入一大堆轴或类似的库:

(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 元素?

4

1 回答 1

5

我认为您的问题可能是您使用xml1->而不是 XML 中的名称空间。XML zip 命名空间中的tag=谓词(在使用关键字 with 时隐含xml1->)默认为自动下降模式,这意味着它在尝试匹配元素标记之前下降到当前节点的子节点。由于根元素已经是 a 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)
于 2013-09-19T17:05:33.953 回答