{"id":51124468,"url":"https://github.com/juliadata/xml.jl","last_synced_at":"2026-06-25T06:01:20.600Z","repository":{"id":38184786,"uuid":"477790967","full_name":"JuliaData/XML.jl","owner":"JuliaData","description":"Read and write XML in pure Julia","archived":false,"fork":false,"pushed_at":"2026-06-19T15:48:19.000Z","size":237,"stargazers_count":97,"open_issues_count":20,"forks_count":17,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-06-19T17:13:47.234Z","etag":null,"topics":["julia","xml"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuliaData.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-04-04T16:50:05.000Z","updated_at":"2026-06-19T15:48:21.000Z","dependencies_parsed_at":"2024-05-18T14:22:02.293Z","dependency_job_id":"28966a91-7975-44fc-9178-fdcacce472c3","html_url":"https://github.com/JuliaData/XML.jl","commit_stats":{"total_commits":61,"total_committers":3,"mean_commits":"20.333333333333332","dds":"0.032786885245901676","last_synced_commit":"e998078b61e72ad3f617e80118674b534402f804"},"previous_names":["juliadata/xml.jl"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/JuliaData/XML.jl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaData%2FXML.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaData%2FXML.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaData%2FXML.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaData%2FXML.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuliaData","download_url":"https://codeload.github.com/JuliaData/XML.jl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaData%2FXML.jl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34761847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["julia","xml"],"created_at":"2026-06-25T06:01:19.637Z","updated_at":"2026-06-25T06:01:20.591Z","avatar_url":"https://github.com/JuliaData.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/JuliaData/XML.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/JuliaData/XML.jl/actions/workflows/CI.yml) [![codecov](https://codecov.io/gh/JuliaData/XML.jl/graph/badge.svg)](https://codecov.io/gh/JuliaData/XML.jl)\n\n\u003ch1 align=\"center\"\u003eXML.jl\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eRead and write XML in pure Julia.\u003c/p\u003e\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Introduction\n\nThis package offers fast data structures for reading and writing XML files with a consistent interface:\n\n\u003cbr\u003e\n\n### `Node`/`LazyNode` Interface:\n\n```\nnodetype(node)      →   XML.NodeType (an enum type)\ntag(node)           →   String or Nothing\nattributes(node)    →   OrderedDict{String, String} or Nothing\nvalue(node)         →   String or Nothing\nchildren(node)      →   Vector{typeof(node)}\nis_simple(node)     →   Bool (whether node is simple .e.g. \u003ctag\u003eitem\u003c/tag\u003e)\nsimple_value(node)   →   e.g. \"item\" from \u003ctag\u003eitem\u003c/tag\u003e)\n```\n\n\u003cbr\u003e\n\n### Extended Interface for `LazyNode`\n\n```\ndepth(node)         →   Int\nnext(node)          →   typeof(node)\nprev(node)          →   typeof(node)\nparent(node)        →   typeof(node)\n```\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Quickstart\n\n```julia\nusing XML\n\nfilename = joinpath(dirname(pathof(XML)), \"..\", \"test\", \"data\", \"books.xml\")\n\ndoc = read(filename, Node)\n\nchildren(doc)\n# 2-Element Vector{Node}:\n#  Node Declaration \u003c?xml version=\"1.0\"?\u003e\n#  Node Element \u003ccatalog\u003e (12 children)\n\ndoc[end]  # The root node\n# Node Element \u003ccatalog\u003e (12 children)\n\ndoc[end][2]  # Second child of root\n# Node Element \u003cbook id=\"bk102\"\u003e (6 children)\n```\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Data Structures that Represent XML Nodes\n\n## Preliminary: `NodeType`\n\n- Each item in an XML DOM is classified by its `NodeType`.\n- Every `XML.jl` struct defines a `nodetype(x)` method that returns its `NodeType`.\n\n| NodeType | XML Representation | `Node` Constructor |\n|----------|--------------------|------------------|\n| `Document` | An entire document | `Document(children...)`\n| `DTD` | `\u003c!DOCTYPE ...\u003e` | `DTD(...) `\n| `Declaration` | `\u003c?xml attributes... ?\u003e` | `Declaration(; attrs...)`\n| `ProcessingInstruction` | `\u003c?tag attributes... ?\u003e` | `ProcessingInstruction(tag; attrs...)`\n| `Comment` | `\u003c!-- text --\u003e` | `Comment(text)`\n| `CData` | `\u003c![CDATA[text]]\u003e` | `CData(text)`\n| `Element` | `\u003ctag attributes... \u003e children... \u003c/NAME\u003e` | `Element(tag, children...; attrs...)`\n| `Text` | the `text` part of `\u003ctag\u003etext\u003c/tag\u003e` | `Text(text)`\n\n\u003cbr\u003e\n\n## `Node`: Probably What You're Looking For\n\n- `read`-ing a `Node` loads the entire XML DOM in memory.\n- See the table above for convenience constructors.\n- `Node`s have some additional methods that aid in construction/mutation:\n\n```julia\n# Add a child:\npush!(parent::Node, child::Node)\n\n# Replace a child:\nparent[2] = child\n\n# Add/change an attribute:\nnode[\"key\"] = value\n\nnode[\"key\"]\n```\n\n- `Node` is an immutable type.  However, you can easily create a copy with one or more field values changed by using the `Node(::Node, children...; attrs...)` constructor where `children` are appended to the source node's children and `attrs` are appended to the node's attributes.\n\n```julia\nnode = XML.Element(\"tag\", \"child\")\n# Node Element \u003ctag\u003e (1 child)\n\nsimple_value(node)\n# \"child\"\n\nnode2 = Node(node, \"added\"; id=\"my-id\")\n# Node Element \u003ctag id=\"my-id\"\u003e (2 children)\n\nnode2.children\n# 2-element Vector{Node}:\n#  Node Text \"child\"\n#  Node Text \"added\"\n```\n\n### Writing `Element` `Node`s with `XML.h`\n\nSimilar to [Cobweb.jl](https://github.com/JuliaComputing/Cobweb.jl#-creating-nodes-with-cobwebh), `XML.h` enables you to write elements with a simpler syntax:\n\n```julia\nusing XML: h\n\njulia\u003e node = h.parent(\n         h.child(\"first child content\", id=\"id1\"),\n         h.child(\"second child content\", id=\"id2\")\n       )\n# Node Element \u003cparent\u003e (2 children)\n\njulia\u003e print(XML.write(node))\n# \u003cparent\u003e\n#   \u003cchild id=\"id1\"\u003efirst child content\u003c/child\u003e\n#   \u003cchild id=\"id2\"\u003esecond child content\u003c/child\u003e\n# \u003c/parent\u003e\n```\n\n\u003cbr\u003e\n\n## `XML.LazyNode`: For Fast Iteration through an XML File\n\nA lazy data structure that just keeps track of the position in the raw data (`Vector{UInt8}`) to read from.\n\n- You can iterate over a `LazyNode` to \"read\" through an XML file:\n\n```julia\ndoc = read(filename, LazyNode)\n\nforeach(println, doc)\n# LazyNode Declaration \u003c?xml version=\"1.0\"?\u003e\n# LazyNode Element \u003ccatalog\u003e\n# LazyNode Element \u003cbook id=\"bk101\"\u003e\n# LazyNode Element \u003cauthor\u003e\n# LazyNode Text \"Gambardella, Matthew\"\n# LazyNode Element \u003ctitle\u003e\n# ⋮\n```\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Reading\n\n```julia\n# Reading from file:\nread(filename, Node)\nread(filename, LazyNode)\n\n# Parsing from string:\nparse(Node, str)\nparse(LazyNode, str)\n\n```\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Writing\n\n```julia\nXML.write(filename::String, node)  # write to file\n\nXML.write(io::IO, node)  # write to stream\n\nXML.write(node)  # String\n```\n\n\n\u003cbr\u003e\u003cbr\u003e\n\n# Performance\n\n- XML.jl performs comparatively to [EzXML.jl](https://github.com/JuliaIO/EzXML.jl), which wraps the C library [libxml2](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home).\n- See the `benchmarks/suite.jl` for the code to produce these results.\n- The following output was generated in a Julia session with the following `versioninfo`:\n\n```\njulia\u003e versioninfo()\nJulia Version 1.9.4\nCommit 8e5136fa297 (2023-11-14 08:46 UTC)\nBuild Info:\n  Official https://julialang.org/ release\nPlatform Info:\n  OS: macOS (arm64-apple-darwin22.4.0)\n  CPU: 10 × Apple M1 Pro\n  WORD_SIZE: 64\n  LIBM: libopenlibm\n  LLVM: libLLVM-14.0.6 (ORCJIT, apple-m1)\n  Threads: 8 on 8 virtual cores\n```\n\n\n### Reading an XML File\n\n```\n       XML.LazyNode   0.009583\n           XML.Node  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1071.32\n      EzXML.readxml  ■■■■■■■■■ 284.346\n   XMLDict.xml_dict  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 1231.47\n```\n\n### Writing an XML File\n\n```\n         Write: XML  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 289.638\n       Write: EzXML  ■■■■■■■■■■■■■ 93.4631\n```\n\n### Lazily Iterating over Each Node\n```\n           LazyNode  ■■■■■■■■■ 51.752\n EzXML.StreamReader  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 226.271\n```\n\n### Collecting All Names/Tags in an XML File\n```\n       XML.LazyNode  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 210.482\n EzXML.StreamReader  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 276.238\n      EzXML.readxml  ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 263.269\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n# Possible Gotchas\n\n- XML.jl doesn't automatically escape special characters (`\u003c`, `\u003e`, `\u0026`, `\"`, and `'` ) for you.  However, we provide utility functions for doing the conversions back and forth:\n  - `XML.escape(::String)` and `XML.unescape(::String)`\n  - `XML.escape!(::Node)` and `XML.unescape!(::Node)`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliadata%2Fxml.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuliadata%2Fxml.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliadata%2Fxml.jl/lists"}