如何在xml属性中获取字符串作为clojure中的小写

时间:2015-02-08 10:54:20

标签: xml clojure

我有以下xml

<?xml version="1.0" encoding="utf-8"?>
<Transformation>
    <ColumnValidations>
        <Column ColumnName="Column1"/>
        <Column ColumnName="Column2" MinInclusive="100" MaxExclusive="10000"/>
        <Column ColumnName="GREGORIAN_DATE" IsDate="Yes" Format="MM/DD/YYYY"/>
    </ColumnValidations>
</Transformation>

使用xml/parsetree-seq,它会生成类似{:ColumnName "Column1"}的内容,是否有简单的方法将所有值转换为地图中的小写(也是属性值) )

xml-content (->> (xml/parse file)
                 (tree-seq :content :content))

2 个答案:

答案 0 :(得分:2)

Tree-sec正在返回一系列地图。作为一种方法,然后将函数映射到对每个映射中的每个值调用.toLower的序列:

 (->> (xml/parse file)
         (tree-seq :content :content)
         (map #(zipmap (keys %) (map clojure.string/lower-case (vals %)))))

假设所有值都是字符串。如果他们不是

,你可能想要或者在那里

答案 1 :(得分:1)

您可以使用fmap中的clojure.algo.generic.functor函数执行类似操作,该函数会映射各种仿函数:

  

将函数f应用于数据结构中的每个项目并返回一个   结构相同。

这意味着您可以转换数据结构中的元素,但与标准map(只能返回延迟序列)不同,它将返回与传入的数据结构相同类型的数据结构。

因此,您可以在xml数据结构上递归fmap,将clojure.string/lower-case应用于您找到的任何字符串:

(ns mynamespace
  (:require [clojure.xml :as xml]
            [clojure.algo.generic.functor :refer [fmap]]
            [clojure.string :as str])
  (:import [java.lang String]
           [java.util List Map]))

(defn lower-case-string-vals [m]
  (fmap (fn [v]
          (cond
           (isa? (type v) String) (str/lower-case v)
           (or (isa? (type v) Map)
               (isa? (type v) List)) (lower-case-string-vals v)
               :else v))
        m))

(lower-case-string-vals (xml/parse "thefile.xml"))

cond的第二部分有点难看:很高兴知道v是否是多方法fmap有实现的类型,但是我我不确定这是可能的,除了尝试捕获。)