hy_odoo/hy_odoo/xml.hy

62 lines
2.5 KiB
Hy

;; Copyright 2019-2022 Fabien Bourgeois <fabien@yaltik.com>
;;
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at https://mozilla.org/MPL/2.0/.
" XML helpers and macros "
(require hy-odoo.mgeneral [instance?]
hy-odoo.modoo [pdb])
(import collections [namedtuple]
functools [partial]
os [path]
xml.etree.ElementTree :as ET)
;; Types
(setv XMLDictElement (namedtuple "XMLDictElement" ["tag" "attrs" "children"]))
;; Helpers
(defn xmlroot [tree]
"Special process for root XML Node"
(setv rootel (.Element ET (get tree "tag") (get tree "attrs")))
(when (in "children" tree)
(xmlchild rootel (get tree "children")))
(return rootel))
(defn xmlchild [parent children]
"Handling of children (ie non root) XML Nodes with/o text and subchildren
(recursive)"
(cond (instance? str children) (setv (. parent text) children)
(instance? XMLDictElement children)
(do
(setv attrs (dfor [k v] (.items (. children attrs)) [(str k) (str v)]))
(setv new-parent (.SubElement ET parent (. children tag) attrs)
subchildren (. children children))
(when subchildren) (xmlchild new-parent subchildren))
(instance? list children) (list( map (partial xmlchild parent) children))
True (raise (TypeError "Invalid arguments for xmlchild"))))
(defn xmln [[tag ""] [attrs {}] [children []]]
"XMLDictElement building from dict object, with defaults"
(when (instance? list attrs) (setv children attrs attrs {}))
(setv xmldictel (partial XMLDictElement tag attrs)
inst-str? (instance? str children))
(when inst-str? (return (xmldictel [children])))
(when (instance? list children) (return (xmldictel children)))
(raise (TypeError "Invalid arguments for xmln")))
(defn xml-write [filepath tree]
"Write XML file according to filepath and given tree"
(when (.endswith filepath ".hy")
(setv output-xml (.decode (.tostring ET
tree
:xml_declaration True
:encoding "utf-8") "utf-8")
output-path (.split (.abspath path filepath) "/")
(get output-path -1) (.replace (get output-path -1) ".hy" "_views.xml")
output-path (.join "/" output-path))
(with [output-file (open output-path "w")] (.write output-file output-xml))))