如何在clojure中将xml属性中的字符串设为小写

How to get the string in xml attributes as lower cases in 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))

您可以使用 clojure.algo.generic.functor 中的 fmap 函数做类似的事情,它映射到各种仿函数:

Applies function f to each item in the data structure s and returns a structure of the same kind.

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

因此您可以递归地 fmap 遍历 xml 数据结构,将 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 具有实现的类型,但我不确定这是否可能,除非使用 try-catch。

Tree-sec 正在返回一系列地图。解决此问题的一种方法是在该序列上映射一个函数,该函数在每个映射中的每个值上调用 .toLower:

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

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

,您可能想在其中放一个或