{"id":13760359,"url":"https://github.com/nilern/Eximia","last_synced_at":"2025-05-10T10:32:24.555Z","repository":{"id":57713663,"uuid":"356280591","full_name":"nilern/Eximia","owner":"nilern","description":"A fast and small XML processor for Clojure. With XML namespace support and secure defaults.","archived":false,"fork":false,"pushed_at":"2021-06-07T08:31:35.000Z","size":117,"stargazers_count":42,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-12T04:26:26.241Z","etag":null,"topics":["clojure","xml","xml-parser","xml-writer"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nilern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["nilern"]}},"created_at":"2021-04-09T13:27:52.000Z","updated_at":"2024-05-31T07:55:11.000Z","dependencies_parsed_at":"2022-09-02T12:11:06.206Z","dependency_job_id":null,"html_url":"https://github.com/nilern/Eximia","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2FEximia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2FEximia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2FEximia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nilern%2FEximia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nilern","download_url":"https://codeload.github.com/nilern/Eximia/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224717810,"owners_count":17357914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","xml","xml-parser","xml-writer"],"created_at":"2024-08-03T13:01:08.651Z","updated_at":"2024-11-16T17:30:59.504Z","avatar_url":"https://github.com/nilern.png","language":"Clojure","funding_links":["https://github.com/sponsors/nilern"],"categories":["Clojure"],"sub_categories":[],"readme":"# Eximia\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.deepbeginnings/eximia.svg)](https://clojars.org/com.deepbeginnings/eximia)\n[![cljdoc badge](https://cljdoc.org/badge/com.deepbeginnings/eximia)](https://cljdoc.org/d/com.deepbeginnings/eximia/CURRENT)\n[![Build Status](https://img.shields.io/github/workflow/status/nilern/eximia/Run%20tests.svg)](https://github.com/nilern/eximia/actions)\n\n\u003e *Eximia Cum Laude Approbatur* or just **E** is the second highest grade in the Finnish Matriculation Exam.\n\u003e It was split off from the highest *Laudatur* grade [in 1996](https://en.wikipedia.org/wiki/XML#History).\n\nA fast and small XML processor for Clojure. With XML namespace support and secure defaults.\n\n## Fast\n\n* About 4x faster than `data.xml` (0.0.8) or `clojure.xml` (Clojure 1.10.3) on read\n* About 3-4x faster than `data.xml` and about 7x faster than `clojure.xml` on write\n\n## Small\n\nOne 300 SLOC namespace.\n\n## Basic Usage\n\nThe requires required for these examples:\n\n```clojure\n\u003e (require '[eximia.core :as exml] '[clojure.java.io :as io])\n```\n\n### Reading\n\n```clojure\n\u003e (with-open [input (io/input-stream \"dev-resources/hello.xml\")]\n    (exml/read input))\n;=\u003e #eximia.core.Element{:tag #qname[greeting], :attrs {#qname[style] \"programmatic\"}, :content [\"Hello, world!\"]}\n\n;; Reader works too (but can be slightly slower):\n\u003e (with-open [input (io/reader \"dev-resources/hello.xml\")]\n    (exml/read input))\n;=\u003e #eximia.core.Element{:tag #qname[greeting], :attrs {#qname[style] \"programmatic\"}, :content [\"Hello, world!\"]}\n\n;; Even slower, just to demonstrate `read-str`:\n\u003e (exml/read-str (slurp \"dev-resources/hello.xml\"))\n;=\u003e #eximia.core.Element{:tag #qname[greeting], :attrs {#qname[style] \"programmatic\"}, :content [\"Hello, world!\"]}\n\n;; javax.xml.namespace.QName:s are used by default, to support XML namespaces.\n;; But keywords can be obtained instead:\n\u003e (with-open [input (io/input-stream \"dev-resources/hello.xml\")]\n    (exml/read input {:tag-fn exml/qname-\u003ekeyword, :key-fn exml/qname-\u003ekeyword}))\n;=\u003e #eximia.core.Element{:tag :greeting, :attrs {:style \"programmatic\"}, :content [\"Hello, world!\"]}\n```\n\n### Writing\n\n```clojure\n\u003e (def tree (exml/-\u003eElement (exml/qname \"greeting\") {(exml/qname \"style\") \"programmatic\"} [\"Hello, world!\"]))\n\n\u003e (exml/write tree System/out)\n; prints \u003c?xml version=\"1.0\" ?\u003e\u003cgreeting xmlns=\"\" style=\"programmatic\"\u003eHello, world!\u003c/greeting\u003e\n;=\u003e nil\n\n;; Writer works too (but can be slightly slower)\n\u003e (exml/write tree *out*)\n; prints \u003c?xml version=\"1.0\" ?\u003e\u003cgreeting xmlns=\"\" style=\"programmatic\"\u003eHello, world!\u003c/greeting\u003e\n;=\u003e nil\n\n;; `write-str` is also available:\n\u003e (exml/write-str tree)\n;=\u003e \"\u003c?xml version=\\\"1.0\\\" ?\u003e\u003cgreeting xmlns=\\\"\\\" style=\\\"programmatic\\\"\u003eHello, world!\u003c/greeting\u003e\"\n\n;; QName:s are used by default, to support XML namespaces. But keywords can be converted on write.\n;; Also while a compact Element record type is provided, any map with the right keys works:\n\u003e (def tree* {:tag :greeting, :attrs {:style \"programmatic\"}, :content [\"Hello, world!\"]})\n\u003e (exml/write tree* System/out {:tag-fn exml/keyword-\u003eqname, :key-fn exml/keyword-\u003eqname})\n; prints \u003c?xml version=\"1.0\" ?\u003e\u003cgreeting xmlns=\"\" style=\"programmatic\"\u003eHello, world!\u003c/greeting\u003e\n;=\u003e nil\n```\n\n## Tip: Non-Standard StAX Implementations\n\nEximia is built on the standard Java StAX cursor API and the JRE ships with an implementation of that. But you might\nwant to look at third-party StAX implementations such as [Woodstox](https://github.com/FasterXML/woodstox) which has\nboth more features (e.g. `IS_VALIDATING`) and better performance. [Aalto](https://github.com/FasterXML/aalto-xml) should\nbe even faster. Although the performance differences might be swamped by all the persistent tree allocations Eximia has\nto do...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilern%2FEximia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnilern%2FEximia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnilern%2FEximia/lists"}