Как я могу отфильтровать только некоторые значения из моего вложенного XML в clojure? - PullRequest
3 голосов
/ 20 июня 2019

У меня есть входной XML, который я преобразовал в clojure-map и могу видеть все значения в одной карте clojure, как эта

Но как я могу отфильтровать определенные значения (mnAmountReceived) из вложенных тегов detail_D1 структуры XML,

Мой 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))

Я пытаюсь отфильтровать mnOrderLineNumber, используя, например, значение 1.0, чтобы я мог получить егосоответствующее значение mnAmountReceived

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

Я хочу отфильтровать mnAmountReceived и узнать, с каким mnOrderLineNumber он поставляется вместе, чтобы я мог отобразить его в своем ответе на соответствующие поля для последующих систем.

1 Ответ

4 голосов
/ 20 июня 2019

Кажется, что вы хотите проанализировать XML и иметь возможность обрабатывать каждый detail_D1 как карту, чтобы вы могли получить номер строки и сумму, полученные вместе.В этом случае одним из подходов может быть использование застежек-молний для анализа данных в структурах данных 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})
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...