xml - 如何仅从 clojure 中的嵌套 XML 中过滤某些值?

标签 xml clojure

我输入的 XML 已转换为 clojure-map,并且可以像这样在一个 clojure 映射中看到所有值

但是如何从嵌套的 detail_D1 标签 XML 结构中过滤出某些值 (mnAmountReceived)。

我的 XML 是这样的,为简洁起见被截断了:

<svResponse category="EVENT" environment="ENV910" pwd="asdfas" 
responseCreator="XAPI" role="ALL" session="7370710" token="asdfasf" 
type="realTimeEvent" user="sv" 
xmlns:rte="http://www.schemas.e1.oracle.com">
    <event>
        <header>
            <eventVersion>1.0</eventVersion>
            <type>EVENTOUT</type>
            <user>sv</user>
            <role>*ALL</role>
           </header>
        <body elementCount="3">
            <detail_D1>
                <szNextStatus>999</szNextStatus>
                <mnOrderLineNumber>1.000</mnOrderLineNumber>
                <mnAmountReceived>100</mnAmountReceived>
            </detail_D1>            
            <detail_D1>
                <szNextStatus>999</szNextStatus>
                <mnOrderLineNumber>2.000</mnOrderLineNumber>
                <mnAmountReceived>200</mnAmountReceived>
            </detail_D1>           
            <detail_D1>
                <szNextStatus>999</szNextStatus>
                <mnOrderLineNumber>3.000</mnOrderLineNumber>
                <mnAmountReceived>300</mnAmountReceived>
            </detail_D1>
        </body>
    </event>
</svResponse>

例如:我想过滤 mnAmountReceived 并根据标签下的 mnOrderLineNumber 将它们分配给单独的键。

我得到一个 xml,我使用以下函数将其转换为 clojure 映射

(xml/parse-str xml-str))
(defn clojurify-xml-map
[clj-xml]
(->> clj-xml
get-body
(map xml->map)
group-and-flattened-source-data))

我正在尝试使用值 1.0 过滤掉 mnOrderLineNumber,例如,这样我就可以获得它对应的 mnAmountReceived 值

(defn filter-price-line [coll]
(filter #(#{1.0} (-> % :mnOrderLineNumber read-string)) coll)
)

我想过滤掉 mnAmountReceived 并知道它与哪个 mnOrderLineNumber 一起出现,以便我可以在对下游系统的适当字段的响应中将其映射出来。

最佳答案

您似乎想要解析 XML 并能够将每个 detail_D1 视为一个映射,以便您可以将行号和数量一起接收。如果是这种情况,一种方法可能是使用 zippers 将数据解析为 Clojure 数据结构,然后使用 filter。这是一个例子:

(ns so
  (:require [clojure.data.xml :as x]
            [clojure.data.zip.xml :as z]
            [clojure.zip :as zip]
            [clojure.java.io :as io]))

(defn parse
  [file]
  (letfn [(parse-detail [z]
            {:next-status     (Integer/parseInt (z/xml1-> z :szNextStatus z/text))
             :line-number     (Double/parseDouble (z/xml1-> z :mnOrderLineNumber z/text))
             :amount-received (Integer/parseInt (z/xml1-> z :mnAmountReceived z/text))})]
    (with-open [r (io/reader file)]
      (let [zipper (->> r x/parse zip/xml-zip)]
        (z/xml-> zipper :svResponse :event :body :detail_D1 parse-detail)))))


(comment
  (parse "input.xml") =>
  ({:next-status 999 :line-number 1.0 :amount-received 100}
   {:next-status 999 :line-number 2.0 :amount-received 200}
   {:next-status 999 :line-number 3.0 :amount-received 300})

  (filter (comp #{1.0} :line-number) (parse "input.xml")) =>
  ({:next-status 999 :line-number 1.0 :amount-received 100})
  )

关于xml - 如何仅从 clojure 中的嵌套 XML 中过滤某些值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56679996/

相关文章:

python - 创建时向 lxml.etree.Element 添加尾部

clojure - 如何在 Windows 上安装 clojure-contrib?

servlets - 在单个 JVM 实例中部署 Clojure 应用程序

Android 菜单背景黑色与 Theme.AppCompat?

java - 从 XML 读取文本时如何忽略标签?

clojure - 嵌套循环语句

performance - Clojure性能: REPL versus uberjar

clojure - 结合 Clojure defprotocol 和 defrecord

java - 无法执行 : javax. ws.rs.NotSupportedException:找不到类型的消息正文阅读器:T 内容类型:application/xml

xml - Dynamics CRM 2011 - 动态添加的 FlyoutAnchor 子菜单按钮被禁用